zoukankan      html  css  js  c++  java
  • bzoj 3514 Codechef MARCH14 GERALD07加强版

    bzoj 3514 Codechef MARCH14 GERALD07加强版

    • 所谓的加强版就是比原题多了个强制在线.原题显然可以莫队随便乱搞一下,就过了.
    • 本题强制在线,我们只能通过预处理的手段,高效回答每次询问.
    • 考虑从前往后依次加入边.如果加入的边是树边,即加入它后图中没有环,那么它会使整张图联通块个数 (-1),否则联通块个数不变.
    • 若加入边 (i) 会成环,我们在环上删掉标号最小的那条边,记这个标号为 (f) ,那么当询问区间的 (l) 大于 (f) 时,边 (i) 就是树边,贡献为 (-1) ,否则贡献为 (0) .
    • (LCT) 来实现删边加边操作,每次查询只需要知道 ([l,r]) 这个区间内有多少 (f) 是小于 (l) 的.用主席树实现即可.
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mp make_pair
    #define pii pair<int,int>
    inline int read()
    {
    	int x=0;
    	bool pos=1;
    	char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())
    		if(ch=='-')
    			pos=0;
    	for(;isdigit(ch);ch=getchar())
    		x=x*10+ch-'0';
    	return pos?x:-x;
    }
    const int inf=1e9;
    const int MAXN=4e5+10;
    int n,m,Q,type;
    namespace LCT{
    	int stk[MAXN],tp;
    	struct node{
    		int ch[2],fa;
    		int val,mn;
    		int rev;
    		node()
    			{
    				ch[0]=ch[1]=fa=0;
    				val=mn=inf;
    				rev=0;
    			}
    	}tree[MAXN];
    	void init(int id)
    		{
    			tree[id+m].val=tree[id+m].mn=id;
    		}
    	#define root tree[x]
    	#define lson tree[root.ch[0]]
    	#define rson tree[root.ch[1]]
    	void pushup(int x)
    		{
    			root.mn=min(root.val,min(lson.mn,rson.mn));
    		}
    	void inverse(int x)
    		{
    			swap(root.ch[0],root.ch[1]);
    			root.rev^=1;
    		}
    	void pushdown(int x)
    		{
    			if(root.rev)
    				{
    					if(root.ch[0])
    						inverse(root.ch[0]);
    					if(root.ch[1])
    						inverse(root.ch[1]);
    					root.rev=0;
    				}
    		}
    	bool isroot(int x)
    		{
    			int y=root.fa;
    			return tree[y].ch[0]!=x && tree[y].ch[1]!=x;
    		}
    	void rotate(int x)
    		{
    			int y=tree[x].fa,z=tree[y].fa;
    			int k=tree[y].ch[1]==x;
    			
    			if(!isroot(y))
    				tree[z].ch[tree[z].ch[1]==y]=x;
    			tree[x].fa=z;
    			
    			tree[y].ch[k]=tree[x].ch[k^1];
    			tree[tree[x].ch[k^1]].fa=y;
    			
    			tree[x].ch[k^1]=y;
    			tree[y].fa=x;
    			pushup(y);
    		}
    	void splay(int x)
    		{
    			tp=0;
    			stk[++tp]=x;
    			for(int pos=x;!isroot(pos);pos=tree[pos].fa)
    				stk[++tp]=tree[pos].fa;
    			while(tp)
    				pushdown(stk[tp--]);
    			while(!isroot(x))
    				{
    					int y=tree[x].fa,z=tree[y].fa;
    					if(!isroot(y))
    						(tree[y].ch[0]==x)^(tree[z].ch[0]==y)?rotate(x):rotate(y);
    					rotate(x);
    				}
    			pushup(x);
    		}
    	void Access(int x)
    		{
    			for(int y=0;x;y=x,x=tree[x].fa)
    				{
    					splay(x);
    					tree[x].ch[1]=y;
    					pushup(x);
    				}
    		}
    	void makeroot(int x)
    		{
    			Access(x);
    			splay(x);
    			inverse(x);
    		}
    	int findroot(int x)
    		{
    			Access(x);
    			splay(x);
    			while(tree[x].ch[0])
    				x=tree[x].ch[0];
    			return x;
    		}
    	void split(int x,int y)
    		{
    			makeroot(x);
    			Access(y);
    			splay(y);
    		}
    	void Link(int x,int y)
    		{
    			makeroot(x);
    			tree[x].fa=y;
    		}
    	void Cut(int x,int y)
    		{
    			split(x,y);
    			tree[y].ch[0]=0;
    			tree[x].fa=0;
    			pushup(y);
    		}
    }
    namespace SEG{
    	struct node{
    		int l,r;
    		int sum,ls,rs;
    	}Tree[MAXN*30];
    	#define Root Tree[o]
    	#define Lson Tree[root.ls]
    	#define Rson Tree[root.rs]
    	int rt[MAXN],idx;
    	void BuildTree(int &o,int l,int r)
    		{
    			o=++idx;
    			Root.sum=0,Root.ls=0,Root.rs=0;
    			Root.l=l,Root.r=r;
    			if(l==r)
    				return;
    			int mid=(l+r)>>1;
    			BuildTree(Root.ls,l,mid);
    			BuildTree(Root.rs,mid+1,r);
    		}
    	void update(int &o,int pre,int pos)
    		{
    			o=++idx;
    			Root=Tree[pre];
    			++Root.sum;
    			int l=Root.l,r=Root.r;
    			if(l==r)
    				return;
    			int mid=(l+r)>>1;
    			if(pos<=mid)
    				update(Root.ls,Tree[pre].ls,pos);
    			else
    				update(Root.rs,Tree[pre].rs,pos);
    		}
    	int query(int o,int L,int R)
    		{
    			if(L>R)	
    				return 0;
    			int l=Root.l,r=Root.r;
    			if(r<L || R<l)
    				return 0;
    			if(L<=l && r<=R)	
    				return Root.sum;
    			int mid=(l+r)>>1;
    			int res=0;
    			if(L<=mid)
    				res+=query(Root.ls,L,R);
    			if(R>mid)
    				res+=query(Root.rs,L,R);
    			return res;
    		}
    }
    int lastans=0;
    int eu[MAXN],ev[MAXN];
    int main()
    {
    //	freopen("7.in","r",stdin);
    //	freopen("ans.out","w",stdout);
    	SEG::idx=0;
    	n=read(),m=read(),Q=read(),type=read();
    	SEG::BuildTree(SEG::rt[0],0,m);
    	for(int i=1;i<=m;++i)
    		{
    		//	cerr<<"solving "<<i<<endl;
    			if(i==9434)
    				{
    					int debug=1;
    				}
    			int u=read(),v=read();
    			if(u==v)
    				{
    					SEG::update(SEG::rt[i],SEG::rt[i-1],i);
    				//	printf("total:%d
    ",SEG::query(SEG::rt[i],0,m-1));
    					continue;
    				}
    			eu[i]=u,ev[i]=v;
    			int ufa=LCT::findroot(u);
    			int vfa=LCT::findroot(v);
    			if(ufa==vfa)
    				{
    					LCT::split(u,v);
    					int id=LCT::tree[LCT::tree[v].ch[0]].mn;
    					LCT::Cut(id+m,eu[id]);
    					LCT::Cut(id+m,ev[id]);
    					LCT::Link(i+m,u);
    					LCT::Link(i+m,v);
    					SEG::update(SEG::rt[i],SEG::rt[i-1],id);
    				}
    			else
    				{
    					LCT::init(i);
    					LCT::Link(i+m,u);
    					LCT::Link(i+m,v);
    					SEG::update(SEG::rt[i],SEG::rt[i-1],0);
    				}
    		//	printf("total:%d
    ",SEG::query(SEG::rt[i],0,m-1));
    		}
    	while(Q--)
    		{
    			int L=read(),R=read();
    			if(type)
    				L^=lastans,R^=lastans;
    			int Rans=SEG::query(SEG::rt[R],0,L-1);
    			int Lans=SEG::query(SEG::rt[L-1],0,L-1);
    			lastans=n-(Rans-Lans);
    			printf("%d
    ",lastans);
    		}
    	return 0;
    }
    
  • 相关阅读:
    OM退货接收设置
    分享一个基于D3.js的互动可重用图表javascript类库 NVD3.js
    免费资源下载:12个漂亮简洁的web背景图案
    分享最新收集的免费photoshop笔刷
    免费素材下载:生态相关的矢量图标集
    分享最新收集的免费photoshop笔刷
    最新的wordpress3.4都有什么新特性
    免费素材下载:学校学院相关图标集
    Adobe开发的基于web的开源代码编辑器 Brackets
    GBin1在线实例帮助你更好的了解jQuery功能特性(三)
  • 原文地址:https://www.cnblogs.com/jklover/p/10417237.html
Copyright © 2011-2022 走看看