bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作

http://www.lydsy.com/JudgeOnline/problem.php?id=2333

读入所有数据,先模拟一遍所有的合并操作

我们不关心联通块长什么样,只关心联通块内有谁

所以可以把一个联通块用一个链表存储

合并x和y时,y的链表整体接到x的链表后面

这样就成了线性结构

按照链表顺序重新给序列标号即可用线段树维护

一遍过,^_^

bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 300001 int a[N]; struct Data
{
char s[];
int x,y;
}data[N]; int fa[N],nxt[N],ed[N]; int id[N],dy[N]; int mx[N<<],f[N<<]; int ans; void read(int &x)
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=f;
} void build(int k,int l,int r)
{
if(l==r)
{
mx[k]=a[id[l]];
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
mx[k]=max(mx[k<<],mx[k<<|]);
} void down(int k)
{
mx[k<<]+=f[k];
mx[k<<|]+=f[k];
f[k<<]+=f[k];
f[k<<|]+=f[k];
f[k]=;
} void add(int k,int l,int r,int opl,int opr,int w)
{
if(l>=opl && r<=opr)
{
f[k]+=w;
mx[k]+=w;
return;
}
if(f[k]) down(k);
int mid=l+r>>;
if(opl<=mid) add(k<<,l,mid,opl,opr,w);
if(opr>mid) add(k<<|,mid+,r,opl,opr,w);
mx[k]=max(mx[k<<],mx[k<<|]);
} void query(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr)
{
ans=max(ans,mx[k]);
return;
}
if(f[k]) down(k);
int mid=l+r>>;
if(opl<=mid) query(k<<,l,mid,opl,opr);
if(opr>mid) query(k<<|,mid+,r,opl,opr);
} int find(int i)
{
return fa[i]==i ? i : fa[i]=find(fa[i]);
} int main()
{
int n,m;
read(n);
for(int i=;i<=n;++i) read(a[i]);
for(int i=;i<=n;++i) fa[i]=i,ed[i]=i;
char s[]; int x,y;
int fx,fy;
read(m);
for(int i=;i<=m;++i)
{
scanf("%s",data[i].s);
if(!(data[i].s[]=='F' && data[i].s[]=='')) read(data[i].x);
if(data[i].s[]=='U' || data[i].s[]=='A' && data[i].s[]!='') read(data[i].y);
if(data[i].s[]=='U')
{
fx=find(data[i].x);
fy=find(data[i].y);
nxt[ed[fx]]=fy;
ed[fx]=ed[fy];
fa[fy]=fx;
}
}
int tot=;
for(int i=;i<=n;++i)
if(find(i)==i)
{
int j=i;
while(j!=ed[i])
{
id[++tot]=j;
dy[j]=tot;
j=nxt[j];
}
id[++tot]=j;
dy[j]=tot;
}
build(,,n);
for(int i=;i<=n;++i) fa[i]=i,ed[i]=i;
int all=;
for(int i=;i<=m;++i)
{
if(data[i].s[]=='U')
{
fx=find(data[i].x);
fy=find(data[i].y);
nxt[ed[fx]]=fy;
ed[fx]=ed[fy];
fa[fy]=fx;
}
else if(data[i].s[]=='A')
{
if(data[i].s[]=='') add(,,n,dy[data[i].x],dy[data[i].x],data[i].y);
else if(data[i].s[]=='') add(,,n,dy[find(data[i].x)],dy[ed[find(data[i].x)]],data[i].y);
else all+=data[i].x;
}
else
{
if(data[i].s[]=='')
{
ans=-1e9;
query(,,n,dy[data[i].x],dy[data[i].x]);
printf("%d\n",ans+all);
}
else if(data[i].s[]=='')
{
ans=-1e9;
query(,,n,dy[find(data[i].x)],dy[ed[find(data[i].x)]]);
printf("%d\n",ans+all);
}
else printf("%d\n",mx[]+all);
}
}
}
上一篇:只能输入数字的文本框-php


下一篇:Photoshop将制作出一本非常逼真的棕色古书