您的位置:首页 > 其它

【LCT】【bzoj 3514】: Codechef MARCH14 GERALD07加强版

2015-05-16 10:22 561 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=3514

感觉不错,一气呵成=w=

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
#define LS c[0]
#define RS c[1]
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
////////////////////////////////////////////////
const int inf=0x3f3f3f3f;
const int N=200010;
int n,m,k,type,sz;
struct node *null;
struct node{
node *c[2],*fa;
bool d(){return this==fa->RS;}
void setc(node *ch,bool d){c[d]=ch;ch->fa=this;}
bool isroot(){return fa->LS!=this&&fa->RS!=this;}
bool rev;
int w,mi;
node *p;
void Flip()
{
if(this==null) return;
rev^=1; swap(LS,RS);
}
void down()
{
if(rev)
{
LS->Flip();
RS->Flip();
rev=0;
}
}
void up()
{
mi=w; p=this;
if(LS->mi < mi) mi=LS->mi,p=LS->p;
if(RS->mi < mi) mi=RS->mi,p=RS->p;
}
void init()
{
c[0]=c[1]=fa=null;
rev=0;
w=mi=inf;
p=this;
}
}T[N*2];
int U
,V
;
int sub
; // 替代边的编号
int blk
; // 联通块的个数
int root
,sum[N*30],ls[N*30],rs[N*30];
////////////////////////////////////////////////
void rot(node *o)
{
node *f=o->fa;
f->down(); o->down();
bool d=o->d();
if(!f->isroot()) f->fa->setc(o,f->d());
else o->fa=f->fa;
f->setc(o->c[!d],d); o->setc(f,!d);
f->up();
}
void splay(node *o)
{
for(o->down();!o->isroot();rot(o));
o->up();
}
void access(node *o)
{
for(node *t=null;o!=null;t=o,o=o->fa)
splay(o),o->RS=t;
}
void makeroot(node *o)
{
access(o); splay(o); o->Flip();
}
node* find(node *o)
{
while(o->fa!=null) o=o->fa;
while(o->LS!=null) o=o->LS;
return o;
}
void split(node *x,node *y)
{
makeroot(x); access(y); splay(y);
}
void link(node *x,node *y)
{
makeroot(x); x->fa=y;
}
void cut(node *x,node *y)
{
split(x,y);
x->fa=y->LS=null;
}
node* query(node *x,node *y)
{
split(x,y);
return y->p;
}
void pre_LCT()
{
sz=n;
blk[0]=n;
rep(i,1,m)
{
int u=U[i],v=V[i];
blk[i]=blk[i-1];
sub[i]=m+1;
if(u==v)
{
sub[i]=i;
continue;
}
sz++;
T[sz].init();
T[sz].mi=T[sz].w=i;
if(find(&T[u])==find(&T[v]))
{
node *t=query(&T[u],&T[v]);
int id=t->w;
sub[i]=id;
cut(t,&T[U[id]]); cut(t,&T[V[id]]);
}
else blk[i]--;
link(&T[sz],&T[u]); link(&T[sz],&T[v]);
}
}
#undef LS
#undef RS
#define LS ls[o],L,mid
#define RS rs[o],mid+1,R
void insert(int lst,int pos,int &o,int L,int R)
{
o=++sz; sum[o]=sum[lst]+1; ls[o]=ls[lst]; rs[o]=rs[lst];
if(L==R) return;
int mid=L+R>>1;
if(pos<=mid) insert(ls[lst],pos,LS);
else insert(rs[lst],pos,RS);
sum[o]=sum[ls[o]]+sum[rs[o]];
}
int query(int x,int o,int L,int R) // [1,o] < x
{
if(o==0 || sum[o]==0) return 0;
if(L==R) return 0;
int mid=L+R>>1;
if(x<=mid) return query(x,LS);
else return sum[ls[o]]+query(x,RS);
}
void pre_SGT()
{
rep(i,1,m) insert(root[i-1],sub[i],root[i],1,m+1);
}
int getans(int l,int r)
{
return blk[r] + ((n-blk[l-1]) - (query(l,root[r],1,m+1) - query(l,root[l-1],1,m+1)));
}
////////////////////////////////////////////////
void input()
{
cin>>n>>m>>k>>type;
null=&T[0]; null->init();
}
void solve()
{
// 1 create vertices
rep(i,1,n) T[i].init();

// 2 input edges
rep(i,1,m) U[i]=read(), V[i]=read();

// 3 pre LCT
pre_LCT();

// 4 pre SGT
pre_SGT();

// 5 output
int lstans=0,L,R;
while(k--)
{
L=read(); R=read();
if(type) L^=lstans,R^=lstans;
printf("%d\n",lstans=getans(L,R));
}
}
////////////////////////////////////////////////
int main()
{
input(),solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: