BZOJ3514: Codechef MARCH14 GERALD07加强版

题解:推荐黄学长的:http://hzwer.com/4358.html

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<map>
#include<queue>
using namespace std;
#define mem1(i,j) memset(i,j,sizeof(i))
#define mem2(i,j) memcpy(i,j,sizeof(i))
#define LL long long
#define up(i,j,n) for(LL i=(j);i<=(n);i++)
#define FILE "ti"
#define poi vec
#define eps 1e-10
#define mid ((l+r)>>1)
const int maxn=202000,inf=1000000000,mod=1000000007;
int read(){
    LL x=0,f=1,ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0',ch=getchar();}
    return f*x;
}
inline bool cmax(int& a,int b){return a<b?a=b,true:false;}
inline bool cmin(int& a,int b){return a>b?a=b,true:false;}
int n,m,k,type;
int x[maxn],y[maxn],t[maxn];
namespace LCT{
	const int maxn=404000;
	int c[maxn][2],fa[maxn],rev[maxn],val[maxn],Min[maxn];
	inline void updata(int o){Min[o]=val[o];cmin(Min[o],Min[c[o][1]]);cmin(Min[o],Min[c[o][0]]);}
	inline void revv(int x){rev[x]^=1,swap(c[x][0],c[x][1]);}
	inline void pushdown(int x){if(rev[x])rev[x]^=1,revv(c[x][0]),revv(c[x][1]);}
	inline bool isroot(int o){return c[fa[o]][1]!=o&&c[fa[o]][0]!=o;}
	inline void rotate(int x){
        int y=fa[x],z=fa[y],d=(c[y][1]==x);
        if(!isroot(y))c[z][c[z][1]==y]=x;
        fa[y]=x;fa[x]=z;if(c[x][d^1])fa[c[x][d^1]]=y;
        c[y][d]=c[x][d^1];c[x][d^1]=y;
        updata(y),updata(x);
    }
	int q[maxn],top=0;
	inline void splay(int x){
        q[++top]=x;
        for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
        while(top)pushdown(q[top--]);
        while(!isroot(x)){
            int y=fa[x];
            if(!isroot(y)){
                if(c[y][1]==x^c[fa[y]][1]==y)rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
	inline void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,updata(x);}
	inline void makeroot(int x){access(x);splay(x);revv(x);}
	inline void cut(int x,int y){makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;updata(y);}
	inline void link(int x,int y){makeroot(x),fa[x]=y;}
	inline void solve(){
		up(i,1,n)val[i]=m+1;
		up(i,1,m)val[i+n]=i;
		Min[0]=inf,val[0]=inf;
		up(i,1,m){
			if(x[i]==y[i]){t[i]=i;continue;}
			makeroot(x[i]),access(y[i]),splay(y[i]);
			int w=c[y[i]][0];
			while(c[w][0])w=c[w][0];
			if(w==x[i]){
				int u=x[Min[y[i]]],v=y[Min[y[i]]],p=Min[y[i]];
				cut(p+n,v),cut(p+n,u);
				link(i+n,x[i]);link(i+n,y[i]);
				t[i]=p;
			}
			else link(x[i],i+n),link(y[i],i+n);
		}
	}
};
namespace zhuxi{
	const int maxn=3800000;
	int c[maxn][2],sum[maxn],rt[maxn],cnt=0;
	int key=0;
	inline void updata(int o){sum[o]=sum[c[o][1]]+sum[c[o][0]];}
	inline void insert(int& o,int x,int l,int r){
		o=++cnt;
		if(l==r){sum[o]=sum[x]+1;return;}
		if(key>mid)c[o][0]=c[x][0],insert(c[o][1],c[x][1],mid+1,r);
		else c[o][1]=c[x][1],insert(c[o][0],c[x][0],l,mid);
		updata(o);
	}
	inline void init(int* h){up(i,1,m)key=t[i],insert(rt[i],rt[i-1],0,m);}
	inline int query(int u,int v,int l,int r){
		int S=0;
		while(true){
			if(key==l&&l==r){S+=sum[v]-sum[u];break;}
			if(key>mid)S+=sum[c[v][0]]-sum[c[u][0]],u=c[u][1],v=c[v][1],l=mid+1;
			else u=c[u][0],v=c[v][0],r=mid;
		}
		return S;
	}
	inline void solve(){
		init(t);
		int last=0;
		while(k--){
			int x=read(),y=read();
			if(type)x^=last,y^=last;
			key=x-1;
			printf("%d\n",last=n-query(rt[x-1],rt[y],0,m));
		}
	}
};
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	n=read(),m=read(),k=read(),type=read();
	up(i,1,m)x[i]=read(),y[i]=read();
	LCT::solve();
	zhuxi::solve();
    return 0;
}

  

posted @ 2017-02-22 18:54  CHADLZX  阅读(108)  评论(0编辑  收藏  举报