1
18
2016
1

[BZOJ 2048] Link Cut Tree

lk砍树的板,记下来好了

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stack>
#define PROC "2049"
using namespace std;
const int maxn=10100;
struct hja{
    hja *fa, *ch[2];
    bool tag;
     
    void gettag()
    {
        tag^=1;
    }
     
    void pushdown()
    {
        if (tag)
        {
            ch[1]->gettag();
            ch[0]->gettag();
            swap(ch[0],ch[1]);
            tag=0;
        }
    }
} rnil;
hja *nil=&rnil;
int n, m;
namespace LCT{
    hja tree[maxn];
    void init(hja &now)
    {
        now.ch[0]=now.ch[1]=now.fa=nil;
    }
    void init()
    {
        for (int i=1; i<=n; i++)
            init(tree[i]);
    }
    bool isRoot(hja *now)
    {
        return now->fa->ch[0]!=now&&now->fa->ch[1]!=now;
    }
    void rotate(hja *now)
    {
        hja *fa=now->fa;
        hja *gfa=fa->fa;
        bool d=fa->ch[1]==now;
        if (!isRoot(fa))
            gfa->ch[gfa->ch[1]==fa]=now;
        now->fa=gfa;
        fa->fa=now;
        fa->ch[d]=now->ch[d^1];
        now->ch[d^1]->fa=fa;
        now->ch[d^1]=fa;
    }
    stack<hja*> sta;
    void splay(hja *now)
    {
        hja *pre=now;
        sta.push(pre);
        while (!isRoot(pre))
        {
            pre=pre->fa;
            sta.push(pre);
        }
        while (!sta.empty())
        {
            sta.top()->pushdown();
            sta.pop();
        }
        while (!isRoot(now))
        {
            hja *fa=now->fa, *gfa=now->fa->fa;
            if (!isRoot(fa))
            {
                if ((gfa->ch[1]==fa)!=(fa->ch[1]==now))
                    rotate(now);
                else
                    rotate(fa);
            }
            rotate(now);
        }
    }
    void access(hja* nowp)
    {
        for (hja *son=nil; nowp!=nil; nowp=nowp->fa)
        {
            splay(nowp);
            nowp->ch[1]=son;
            son=nowp;
        }
    }
    void access(int nowp)
    {
        access(&tree[nowp]);
    }
 
    void makeRoot(hja* nowp)
    {
        access(nowp);
        splay(nowp);
        nowp->gettag();
    }
    void makeRoot(int nowp)
    {
        makeRoot(&tree[nowp]);
    }
    void cut(hja* p1, hja* p2)
    {
        makeRoot(p1);
        access(p2);
        splay(p2);
        p1->fa=nil;
        p2->ch[0]=nil;
    }
    void cut(int p1, int p2)
    {
        cut(&tree[p1],&tree[p2]);
    }
    hja* find(hja *p1)
    {
        access(p1);
        splay(p1);
        while (p1->ch[0]!=nil)
            p1=p1->ch[0];
        return p1;
    }
    int find(int nowp)
    {
        return find(&tree[nowp])-tree;
    }
    bool find(int p1, int p2)
    {
        return find(p1)==find(p2);
    }
    bool find(hja* p1, hja* p2)
    {
        return find(p1)==find(p2);
    }
    void link(hja* p1, hja* p2)
    {
        makeRoot(p1);
        p1->fa=p2;
        access(p1);
    }
    void link(int p1, int p2)
    {
        link(&tree[p1],&tree[p2]);
    }
}
 
char s[10];
 
int main()
{
#ifdef YJQ_LOCAL
    freopen(PROC".in","r",stdin);
//  freopen(PROC".out","w",stdout);
#endif
    int tmp1,tmp2,tmp3;
    scanf("%d%d",&n,&m);
    LCT::init();
    while(m--)
    {
        scanf("%s%d%d",s+1,&tmp1,&tmp2);
        if (s[1]=='Q')
            puts(LCT::find(tmp1,tmp2)?"Yes":"No");
        if (s[1]=='C')
            LCT::link(tmp1,tmp2);
        if (s[1]=='D')
            LCT::cut(tmp1,tmp2);
    }
    fclose(stdout);
    return 0;
}
Category: 模板 | Tags: Link Cut Tree 模板
11
13
2015
0

[BZOJ 4318] OSU!

期望题,维护期望和平方的期望就可以计算

#include <cstdio>
#include <memory.h>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cctype>
 
using namespace std;
 
void read(double &num)
{
    num=0;
    bool after=0;
    double bei=1;
    char tmpc;
    do
    {
        tmpc=getchar();
    }
    while (!isdigit(tmpc));
    while (isdigit(tmpc))
    {
        if (after)
        {
            bei/=10;
            num=num+(tmpc-'0')*bei;
        }
        else
            num=num*10+tmpc-'0';
        tmpc=getchar();
        if (tmpc=='.')
        {
            after=1;
            tmpc=getchar();
        }
    }
}
int main() {
    register int n;
    scanf("%d",&n);
    register double f = 0,g = 0,ans = 0, p;
    while (n--) {
        read(p);
        ans += (3*f+3*g+1)*p;
        g = (g+2*f+1) * p;
        f = (f+1) * p;
    }
    printf("%.1f\n",ans);
}
Category: 动态规划 | Tags:
11
13
2015
0

[BZOJ 1077] 天平

Description

你有n个砝码,均为1克,2克或者3克。你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系。你把其中两个砝码A和B放在天平的左边,需要另外选出两个砝码放在天平的右边。问:有多少种选法使得天平的左边重(c1)、一样重(c2)、右边重(c3)?(只有结果保证惟一的选法才统计在内)

暴力枚举,暴力判断

#include<cstdio>
#include<algorithm>
#include<cstring>
#define PROC "scale"
using namespace std;
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
typedef long long LL;
int n, a, b;
const int maxn=52, inf=0x3f3f3f3f;
char mp[maxn][maxn];
int belong[maxn], bn;
struct yjq{
	int rel[maxn];
	bool able[4];
	yjq()
	{
		memset(able,true,sizeof(able));
		memset(rel,0x3f,sizeof(rel));
	}
};
yjq naive[maxn];
int fa[maxn];

int findfa(int son)
{
	if (son!=fa[son]) fa[son]=findfa(fa[son]);
	return fa[son];
}

void addfa(int s1, int s2)
{
	int f1=findfa(s1), f2=findfa(s2);
	fa[f2]=f1;
}

void init()
{
	bn=n;
	for (int i=1; i<=n; i++)
		fa[i]=i;
	for (int i=1; i<=n; i++)
	{
		for (int j=1; j<=n; j++)
		{
			if (mp[i][j]=='=')
			{
				addfa(i,j);
			}
		}
	}
	for (int i=1; i<=n; i++)
		belong[i]=findfa(i);
	for (int i=1; i<=n; i++)
	{
		for (int j=1; j<=n; j++)
		{
			if (mp[i][j]=='-')
			{
				naive[belong[i]].rel[belong[j]]=1;
				naive[belong[i]].able[3]=0;
				naive[belong[j]].rel[belong[i]]=-1;
				naive[belong[j]].able[1]=0;
			}
			else if (mp[i][j]=='+')
			{
				naive[belong[i]].rel[belong[j]]=-1;
				naive[belong[i]].able[1]=0;
				naive[belong[j]].rel[belong[i]]=1;
				naive[belong[j]].able[3]=0;
			}
		}
	}
	for (int i=1; i<=bn; i++)
	{
		for (int j=1; j<=bn; j++)
		{
			for (int k=1; k<=bn; k++)
			{
				if (naive[i].rel[j]==1&&naive[i].rel[j]==naive[j].rel[k])
				{
					naive[i].rel[k]=2;
					naive[i].able[2]=0;
					naive[k].rel[i]=-2;
					naive[k].able[2]=0;
				}
			}
		}
	}
}
int cnt[4];
int getres(int num1, int num2)
{
	if (num1>num2) return 1;
	if (num1<num2) return 3;
	return 2;
}

int st[5], sw[5];

bool illegal(int s1, int s2, int s3, int s4, int w1, int w2, int w3, int w4)
{
	st[1]=belong[s1];
	st[2]=belong[s2];
	st[3]=belong[s3];
	st[4]=belong[s4];
	sw[1]=w1;
	sw[2]=w2;
	sw[3]=w3;
	sw[4]=w4;
	for (int i=1; i<=4; i++)
	{
		if (!naive[st[i]].able[sw[i]]) return 1;
		for (int j=i+1; j<=4; j++)
		{
			if (st[i]==st[j]&&sw[i]!=sw[j]) return 1;
			int delta=naive[st[i]].rel[st[j]];
			if (delta==inf) continue;
			if (delta>0)
			{
				if (sw[i]+delta>sw[j]) return 1;
			}
			else
			{
				if (sw[i]+delta<sw[j]) return 1;
			}
		}
	}
	return 0;
}

void solve()
{
	for (int c=1; c<n; c++)
	{
		if (c==a||c==b) continue;
		for (int d=c+1; d<=n; d++)
		{
			if (d==a||d==b||d==c) continue;
			int res=0;
			for (int w1=1; w1<=3; w1++)
			{
				for (int w2=1; w2<=3; w2++)
				{
					for (int w3=1; w3<=3; w3++)
					{
						for (int w4=1; w4<=3; w4++)
						{
							if (illegal(a,b,c,d,w1,w2,w3,w4)) continue;
//							printf("%d:%d %d:%d %d:%d %d:%d\n",a,w1,b,w2,c,w3,d,w4);
							int back=getres(w1+w2,w3+w4);
							if (back!=res && res!=0)
							{
								res=-1;
								break;
							}
							if (!res) res=back;
						}
					}
				}
			}
			if (res!=-1)
				cnt[res]++;
		}
	}
}

int main()
{
//	freopen(PROC".in","r",stdin);
//	freopen(PROC".out","w",stdout);
	scanf("%d%d%d",&n,&a,&b);
	for (int i=1; i<=n; i++)
		scanf("%s",&mp[i][1]);
	init();
	solve();
	for (int i=1; i<=2; i++)
		printf("%d ",cnt[i]);
	printf("%d\n",cnt[3]);
	fclose(stdout);
	return 0;
}
Category: 黑暗算法 | Tags: 暴力
11
13
2015
0

[BZOJ 1076] 奖励关

Description

你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关。在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃)。 宝物一共有n种,系统每次抛出这n种宝物的概率都相同且相互独立。也就是说,即使前k-1次系统都抛出宝物1(这种情况是有可能出现的,尽管概率非常小),第k次抛出各个宝物的概率依然均为1/n。 获取第i种宝物将得到Pi分,但并不是每种宝物都是可以随意获取的。第i种宝物有一个前提宝物集合Si。只有当Si中所有宝物都至少吃过一次,才能吃第i种宝物(如果系统抛出了一个目前不能吃的宝物,相当于白白的损失了一次机会)。注意,Pi可以是负数,但如果它是很多高分宝物的前提,损失短期利益而吃掉这个负分宝物将获得更大的长期利益。 假设你采取最优策略,平均情况你一共能在奖励关得到多少分值?

状压DP

只需要记录当前吃了哪些东西,就可以转移辣

从后往前DP比较方便,注意判断非法状态

#include<cstdio>
#include<algorithm>
#include<cstring>
#define PROC "bonus"
using namespace std;
#define pos(x) (1<<((x)-1))
double dp[110][1<<15];
int k,n;
int score[17];
int need[17];
bool use[1<<15];

bool legal(int status)
{
	for (int i=1; i<=n; i++)
	{
		if (status&pos(i))
		{
			if ((status&need[i])!=need[i])
				return 0;
		}
	}
	return 1;
}

void to2(int num)
{
	if (num>1) to2(num>>1);
	putchar('0'+(num&1));
}

int main()
{
//	freopen(PROC".in","r",stdin);
	scanf("%d%d",&k,&n);
	int nown, tmp1;
	for (int i=1; i<=n; i++)
	{
		scanf("%d",&score[i]);
		nown=0;
		while (1)
		{
			scanf("%d",&tmp1);
			if (!tmp1) break;
			need[i]|=pos(tmp1);
		}
	}
	for (int j=0; j<(1<<n); j++)
	{
		bool suc=legal(j);
		if (suc) dp[k][j]=0;
		else dp[k][j]=-0x3f3f3f3f;
		use[j]=suc;
	}
	for (register int i=k-1; i>=0; i--)
	{
		for (register int l=0; l<(1<<n); l++)
		{
			if (!use[l])
			{
				dp[i][l]=-0x3f3f3f3f;
				continue;
			}
			for (register int j=1; j<=n; j++)
			{
				dp[i][l]+=(double)max(dp[i+1][l],dp[i+1][l|pos(j)]+score[j]);
			}
			dp[i][l]/=n;
		}
	}
	printf("%.6f\n",dp[0][0]);
	fclose(stdout);
	return 0;
}

 

Category: 动态规划 | Tags: DP 状压dp
11
13
2015
0

[BZOJ 3196] 二逼平衡树

树状数组套主席树做法,动态建树卡空间过了。

速度还行。

/**************************************************************
    Problem: 3196
    User: Shimakaze
    Language: C++
    Result: Accepted
    Time:2092 ms
    Memory:119584 kb
****************************************************************/
 
#include<cstdio>
#include<algorithm>
#include<cstring>
#define PROC "1"
using namespace std;
const int maxn=50010;
struct yjq{
    int l,r,k;
    char type;
};
yjq opt[maxn];
int hash[maxn*2], a[maxn], hn, n, m;
 
struct seg{
    int sum, L, R;
};
seg tree[maxn*200];
int nn, root[maxn];
 
void update(int num)
{
    tree[num].sum=tree[tree[num].L].sum+tree[tree[num].R].sum;
}
 
void modify(int &num, int L, int R, int pos, int v)
{
    if (!num)
        num=++nn;
    if (L==R)
    {
        tree[num].sum+=v;
        return;
    }
    int mid=(L+R)>>1;
    if (pos<=mid)
        modify(tree[num].L,L,mid,pos,v);
    else
        modify(tree[num].R,mid+1,R,pos,v);
    update(num);
}
#define lowbit(x) ((x)&(-(x)))
void modify(int pos, int val, int v)
{
    for (int i=pos; i<=n; i+=lowbit(i))
        modify(root[i],1,hn,val,v);
}
 
void build()
{
    for (int i=1; i<=n; i++)
        modify(i,a[i],1);
}
 
int left[100], right[100], ln, rn;
 
void init(int l, int r)
{
    ln=rn=0;
    for (int i=l-1; i; i-=lowbit(i))
        left[++ln]=root[i];
    for (int i=r; i; i-=lowbit(i))
        right[++rn]=root[i];
}
 
void walkleft()
{
    for (int i=1; i<=ln; i++)
        left[i]=tree[left[i]].L;
    for (int i=1; i<=rn; i++)
        right[i]=tree[right[i]].L;
}
 
void walkright()
{
    for (int i=1; i<=ln; i++)
        left[i]=tree[left[i]].R;
    for (int i=1; i<=rn; i++)
        right[i]=tree[right[i]].R;
}
 
int getsum()
{
    int sum=0;
    for (int i=1; i<=ln; i++)
        sum-=tree[left[i]].sum;
    for (int i=1; i<=rn; i++)
        sum+=tree[right[i]].sum;
    return sum;
}
 
int getlsum()
{
    int sum=0;
    for (int i=1; i<=ln; i++)
        sum-=tree[tree[left[i]].L].sum;
    for (int i=1; i<=rn; i++)
        sum+=tree[tree[right[i]].L].sum;
    return sum;
}
 
int getrsum()
{
    int sum=0;
    for (int i=1; i<=ln; i++)
        sum-=tree[tree[left[i]].R].sum;
    for (int i=1; i<=rn; i++)
        sum+=tree[tree[right[i]].R].sum;
    return sum;
}
 
int querysum(int L, int R, int r)
{
    if (r==R)
        return getsum();
    int mid=(L+R)>>1;
    if (r<=mid)
    {
        walkleft();
        return querysum(L,mid,r);
    }
    else
    {
        int nowsum=getlsum();
        walkright();
        return nowsum+querysum(mid+1,R,r);
    }
}
 
int querynum(int L, int R, int rank)
{
    if (L==R)
        return L;
    int mid=(L+R)>>1;
    int lsum=getlsum();
    if (lsum>=rank)
    {
        walkleft();
        return querynum(L,mid,rank);
    }
    else
    {
        rank-=lsum;
        walkright();
        return querynum(mid+1,R,rank);
    }
}
 
int Queryrank(int l, int r, int v)
{
    init(l,r);
    return querysum(1,hn,v-1)+1;
}
 
int Querynum(int l, int r, int rank)
{
    init(l,r);
    return querynum(1,hn,rank);
}
 
int Querypre(int l, int r, int num)
{
    return Querynum(l,r,Queryrank(l,r,num)-1);
}
 
int Querynext(int l, int r, int num)
{
    return Querynum(l,r,Queryrank(l,r,num+1));
}
 
void readInfo()
{
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        hash[++hn]=a[i];
    }
    int type, l, r, k;
    for (int i=1; i<=m; i++)
    {
        scanf("%d",&type);
        opt[i].type=type;
        if (type==3)
        {
            scanf("%d%d",&l,&k);
            opt[i].l=l;
            opt[i].k=k;
            hash[++hn]=k;
            continue;
        }
        scanf("%d%d%d",&l,&r,&k);
        opt[i].l=l;
        opt[i].r=r;
        opt[i].k=k;
        if (type!=2)
            hash[++hn]=k;
    }
    sort(hash+1,hash+1+hn);
    hn=unique(hash+1,hash+1+hn)-hash-1;
    for (int i=1; i<=n; i++)
        a[i]=lower_bound(hash+1,hash+1+hn,a[i])-hash;
    for (int i=1; i<=m; i++)
        if (opt[i].type!=2)
            opt[i].k=lower_bound(hash+1,hash+1+hn,opt[i].k)-hash;
}
 
int main()
{
#ifdef YJQ_LOCAL
    freopen(PROC".in","r",stdin);
#endif
    readInfo();
    build();
    for (int i=1; i<=m; i++)
    {
//      printf("now %d %d %d %d\n",opt[i].type,opt[i].l,opt[i].r,opt[i].k); 
        if (opt[i].type==1)
            printf("%d\n",Queryrank(opt[i].l,opt[i].r,opt[i].k));
        if (opt[i].type==2)
            printf("%d\n",hash[Querynum(opt[i].l,opt[i].r,opt[i].k)]);
        if (opt[i].type==3)
        {
            int pos=opt[i].l;
            modify(pos,a[pos],-1);
            a[pos]=opt[i].k;
            modify(pos,a[pos],1);
        }
        if (opt[i].type==4)
            printf("%d\n",hash[Querypre(opt[i].l,opt[i].r,opt[i].k)]);
        if (opt[i].type==5)
            printf("%d\n",hash[Querynext(opt[i].l,opt[i].r,opt[i].k)]);
    }
    fclose(stdout);
    return 0;
}
10
1
2015
0

[BZOJ 2502] 清理雪道

Description

滑雪场坐落在FJ省西北部的若干座山上。从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向。

你的团队负责每周定时清理雪道。你们拥有一架直升飞机,每次飞行可以从总部带一个人降落到滑雪场的某个地点,然后再飞回总部。从降落的地点出发,这个人可以顺着斜坡向下滑行,并清理他所经过的雪道。由于每次飞行的耗费是固定的,为了最小化耗费,你想知道如何用最少的飞行次数才能完成清理雪道的任务。

 

求无源汇的网络流最小流。

首先构造源点S和汇点T,从源点向每个点连INF流量表示可以从每个点开始滑行无数次,从每个点向汇点连INF表示可以从每个点结束滑行无数次。原图中的边每条边流量下界为1,流量上界INF(可经过无数次),然后求满足条件的最小流。

构造超级源SS和超级汇TT,按照带流量下界的可行流做法,对于一条u->v流量上界为a且下界为b的边,连SS->v流量上限b,u->TT流量上限为b,u->v流量上限为a-b。原汇点T->S连一条流量上限为INF的边。

先跑一次网络流,T->S的边的流量记为x,然后拆掉超级源和超级汇以及T->S的边,将T作为原点、S作为汇点再跑一次网络流,答案记为y,则最小流为x-y。(对于本题必定有解,否则要判断所有上限为b的边是否满流,若不满流则无解)

 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue> 
using namespace std;

#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
const int maxn=500, inf=0x3f3f3f3f;
typedef long long LL;
struct tyh{
	int f,t,flow,n;
};
tyh naive[maxn * maxn];
int head[maxn], top[maxn], nn=1;
int S, T, SS, TT, n;
queue<int> q;
bool chk[maxn];
int dep[maxn], ans;

void addedge(int f, int t, int flow)
{
	nn++;
	naive[nn].f=f;
	naive[nn].t=t;
	naive[nn].flow=flow;
	naive[nn].n=head[f];
	head[f]=nn;
}

void link(int f, int t, int flow)
{
	addedge(f,t,0);
	addedge(t,f,flow);
}

bool bfs()
{
	int nowp=SS;
	q.push(nowp);
	memset(dep,0,sizeof(dep));
	dep[nowp]=1;
	while (!q.empty())
	{
		nowp=q.front();
		q.pop();
		for (int e=head[nowp]; e; e=naive[e].n)
		{
//			printf("%d\n",naive[e^1].flow);
			if (naive[e^1].flow)
			{
				if (!dep[naive[e].t])
				{
					dep[naive[e].t]=dep[nowp]+1;
					q.push(naive[e].t);
				}
			}
		}
	}
	return dep[TT];
}

int dfs(int nowp, int flow)
{
	if (nowp==TT) return flow;
//	printf("%d %d[from %d to %d]\n",nowp,flow,SS,TT);
	int used=0;
	for (int &e=top[nowp]; e; e=naive[e].n)
	{
//		printf("%d--%d\n",dep[nowp],dep[naive[e].t]);
		if (naive[e^1].flow&&(dep[naive[e].t]==dep[nowp]+1))
		{
//			printf("==>%d\n",naive[e].t);
			int tmp1=dfs(naive[e].t,min(flow-used,naive[e^1].flow));
			used+=tmp1;
			naive[e].flow+=tmp1;
			naive[e^1].flow-=tmp1;
			if (used==flow)
				return used;
		}
	}
	if (!used)
		dep[nowp]=0;
	return used;
}

int dinic()
{
	int ans=0;
	while (bfs())
	{
		for (int i=1; i<=TT; i++)
			top[i]=head[i];
		ans+=dfs(SS,inf);
	}
	return ans;
}

void rebuild()
{
	for (int e=2; e<=nn; e++)
	{
		if (naive[e].f==SS||naive[e].t==SS||naive[e].f==TT||naive[e].t==TT)
			naive[e].flow=0; 
	}
	link(SS,T,inf);
	link(S,TT,inf);
}

int main()
{
	int num, to, cost;
	scanf("%d",&n);
	S=n+1;
	T=n+2;
	SS=n+3;
	TT=n+4;
	for (int i=1; i<=n; i++)
	{
		scanf("%d",&num);
		link(S,i,inf);
		link(i,T,inf);
		for (int j=1; j<=num; j++)
		{
			scanf("%d",&to);
			link(i,to,inf);
			link(SS,to,1);
		}
		if (num) link(i,TT,num);
	}
	link(T,S,inf);
//	for (int e=2; e<=nn; e+=2)
//		printf("%d==%d==>%d\n",naive[e].f,naive[e^1].flow,naive[e].t);
//	while(1);
	int TtoS=nn^1;
	dinic();
	int ans1=naive[TtoS].flow;
	
	naive[TtoS].flow = 0;
	naive[TtoS^1].flow = 0;
	rebuild();
	int ans2=dinic();
	printf("%d\n",ans1-ans2);
	return 0;
}
Category: 网络流 | Tags: 网络流
8
5
2015
0

[BZOJ 2463][中山市选2009]谁能赢呢?

最短代码 感谢高新的呆萌小帅哥(C,非C++)

main(n){while(scanf("%d",&n),n)puts(n&1?"Bob":"Alice");}
Category: 杂题 | Tags: 压代码
8
5
2015
0

[BZOJ 3170][TJOI 2013]松鼠聚会

首先造几组数据,可以发现把每个点按x+y排序后取中位数,然后在中位数左右的点枚举,随机数据是卡不到的,而且我感到要构造数据很麻烦,所以就这么写了。

#include<cstdio>
#include<algorithm>
using namespace std;
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
typedef long long LL;
#define debug
const int maxn=100100, canshu=500;
int mid, n;
struct yjq{
    int x,y;
    void read()
    {
        scanf("%d%d",&x,&y);
    }
};
yjq poi[maxn];
LL ans;
 
inline bool cmpx(yjq ac, yjq ak)
{
    return ac.x<ak.x;
}
 
inline bool cmp(yjq ac, yjq ak)
{
    return ac.x+ac.y<ak.x+ak.y;
}
 
inline bool cmpy(yjq ac, yjq ak)
{
    return ac.y<ak.y;
}
 
inline int dist(yjq ac, yjq ak)
{
    return max(abs(ac.x-ak.x),abs(ac.y-ak.y));
}
 
inline LL calcans(yjq ac)
{
    LL nowans=0;
    for (int j=1; j<=n; j++)
        nowans+=dist(ac,poi[j]);
    return nowans;
}
 
void baoli()
{
    for (int i=1; i<=n; i++)
    {
        ans=min(ans,calcans(poi[i]));
    }
    printf(lld"\n",ans);
}
 
int main()
{
    scanf("%d",&n);
    mid=(n+1)>>1;
    for (int i=1; i<=n; i++)
        poi[i].read();
    ans=0x3f3f3f3f3f3f3f3fLL;
#ifdef debug
    if (n<=1000)
    {
        baoli();
        return 0;
    }
#endif
    sort(poi+1,poi+1+n,cmp);
    ans=min(ans,calcans(poi[mid]));
    for (int i=1; i<=300; i++)
    {
        ans=min(ans,calcans(poi[mid+i]));
        ans=min(ans,calcans(poi[mid-i]));
    }
    printf(lld"\n",ans);
    fclose(stdout);
    return 0;
}
Category: 黑暗算法 | Tags: 黑暗算法
8
4
2015
0

【模板】Suffix Automaton

sro YJQ orz

#include<cstdio>
#include<cstring>
const int maxm=26, maxn=101000;

struct node{
	int par, val;
	int go[maxm];
};
node sam[maxn*2];
int sn;
int root,last;
char read[maxn];
int number[maxn];

struct yjq{
	int f, t, n;
};
yjq naive[maxn<<2];
int nn, pre[maxn<<1], fst[maxn<<1];

bool end[maxn<<1];

void addedge(int f, int t)
{
	nn++;
	naive[nn].f=f;
	naive[nn].t=t;
	if (fst[f])	
		naive[pre[f]].n=nn;
	else
		fst[f]=nn;
	pre[f]=nn;
}

void extend(int now)
{
	sn++;
	sam[sn].val=sam[last].val+1;
	int p=last;
	int np=sn;
	for (; p&&(!sam[p].go[now]); p=sam[p].par)
		sam[p].go[now]=np;
	if (!p)
		sam[np].par=root;
	else
	{
		int q=sam[p].go[now];
		if (sam[q].val==sam[p].val+1)
			sam[np].par=q;
		else
		{
			int nq=++sn;
			sam[nq].val=sam[p].val+1;
			memcpy(sam[nq].go,sam[q].go,sizeof sam[q].go);
			sam[nq].par=sam[q].par;
			sam[q].par=nq;
			sam[np].par=nq;
			for (; p&&sam[p].go[now]==q; p=sam[p].par)
			{
				sam[p].go[now]=nq;
			}
		}
	}
	last=np;
}

void walk_sam(int nowp)
{
	for (int c=0; c<maxm; c++)
	{
		if (sam[nowp].go[c])
		{
			printf("%d --%c-> %d\n",nowp,c+'a',sam[nowp].go[c]);
		}
	}
}

int main()
{
	scanf("%s",read+1);
	int n=strlen(read+1);
	root=last=1;
	sn=1;
	for (int i=1; i<=n; i++)
	{
		number[i]=read[i]-'a';
		extend(number[i]);
	}
	for (int i=root; i<=sn; i++)
		addedge(sam[i].par,i);
	dfs(root);
	return 0;
}

 

Category: 模板 | Tags: 模板 后缀自动机

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com