zoukankan      html  css  js  c++  java
  • 【BZOJ3514】— Codechef MARCH14 GERALD07加强版(LCT+主席树)

    传送门


    考虑按照编号依次把点加入
    假设当前加入边ii,如果形成了环
    将环上最小的边xx删去,并记f[i]=xf[i]=x

    考虑一次询问l,rl,r
    如果i[l,r],f[i][l,r]iin[l,r],f[i]in[l,r]
    那么边ii加进去就不会形成连通块

    于是考虑统计满足这样的ii的个数
    用主席树就完了

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    const int mod=998244353,g=3;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    inline void Add(int &a,int b){a=add(a,b);}
    inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
    inline void Dec(int &a,int b){a=dec(a,b);}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=400005;
    namespace Lct{
    	int fa[N],son[N][2],mn[N],id[N],val[N],rev[N];
    	#define lc(u) son[u][0]
    	#define rc(u) son[u][1]
    	inline bool isrc(int u){
    		return rc(fa[u])==u;
    	}
    	inline bool isrt(int u){
    		return lc(fa[u])!=u&&rc(fa[u])!=u;
    	}
    	inline void pushup(int u){
    		id[u]=u,mn[u]=val[u];
    		if(lc(u)&&mn[lc(u)]<mn[u])mn[u]=mn[lc(u)],id[u]=id[lc(u)];
    		if(rc(u)&&mn[rc(u)]<mn[u])mn[u]=mn[rc(u)],id[u]=id[rc(u)];
    	}
    	inline void pushdown(int u){
    		if(!rev[u])return;
    		if(lc(u))rev[lc(u)]^=1;
    		if(rc(u))rev[rc(u)]^=1;
    		swap(lc(u),rc(u));
    		rev[u]=0;
    	}
    	inline void rotate(int v){
    		int u=fa[v],z=fa[u];
    		int t=rc(u)==v;
    		fa[v]=z;
    		if(!isrt(u))son[z][rc(z)==u]=v;
    		fa[son[v][t^1]]=u,son[u][t]=son[v][t^1];
    		son[v][t^1]=u,fa[u]=v;
    		pushup(u),pushup(v);
    	}
    	int stk[N],top;
    	inline void splay(int u){
    		stk[top=1]=u;
    		for(int v=u;!isrt(v);v=fa[v])stk[++top]=fa[v];
    		for(int i=top;i;i--)pushdown(stk[i]);
    		while(!isrt(u)){
    			if(!isrt(fa[u]))
    			isrc(u)==isrc(fa[u])?rotate(fa[u]):rotate(u);
    			rotate(u);
    		}
    	}
    	inline void access(int u){
    		for(int v=0;u;v=u,u=fa[u]){
    			splay(u),rc(u)=v;
    			if(v)fa[v]=u;
    			pushup(u);
    		}
    	}
    	inline void makert(int u){
    		access(u),splay(u),rev[u]^=1;
    	}
    	inline void link(int u,int v){
    		makert(u),splay(v),fa[u]=v,pushup(v);
    	}
    	inline void cut(int u,int v){
    		makert(u),access(v),splay(v);
    		lc(v)=fa[u]=0;pushup(v);
    	}
    }
    namespace Pt{
    	cs int M=N*25;
    	int tot,lc[M],rc[M],rt[N],siz[M];
    	#define mid ((l+r)>>1)
    	inline void insert(int r1,int &u,int l,int r,int p){
    		u=++tot;
    		siz[u]=siz[r1]+1,lc[u]=lc[r1],rc[u]=rc[r1];
    		if(l==r)return;
    		if(p<=mid)insert(lc[r1],lc[u],l,mid,p);
    		else insert(rc[r1],rc[u],mid+1,r,p);
    	}
    	inline int query(int u,int l,int r,int st,int des){
    		if(!u)return 0;
    		if(st<=l&&r<=des)return siz[u];
    		int res=0;
    		if(st<=mid)res+=query(lc[u],l,mid,st,des);
    		if(mid<des)res+=query(rc[u],mid+1,r,st,des);
    		return res;
    	}
    }
    int n,m,q,last,tp;
    int f[N];
    struct edge{
    	int u,v;
    }e[N];
    int fa[N];
    inline int find(int x){
    	return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    int main(){
    	n=read(),m=read(),q=read(),tp=read();
    	for(int i=1;i<=n;i++)Lct::val[i]=1e9,fa[i]=i;
    	for(int i=1;i<=m;i++){
    		e[i].u=read(),e[i].v=read();
    		Lct::val[i+n]=i;
    	}
    	for(int i=1;i<=m;i++){
    		int u=e[i].u,v=e[i].v;
    		if(u==v){f[i]=i;continue;}
    		int f1=find(u),f2=find(v);
    		if(f1!=f2){
    			fa[f1]=f2,Lct::link(i+n,u),Lct::link(i+n,v);
    		}
    		else{
    			Lct::makert(u),Lct::access(v),Lct::splay(v);
    			int mpos=Lct::id[v]-n;f[i]=mpos;
    			Lct::cut(e[mpos].u,mpos+n),Lct::cut(e[mpos].v,mpos+n);
    			Lct::link(i+n,u),Lct::link(i+n,v);
    		}
    	}
    	for(int i=1;i<=m;i++)if(f[i])Pt::insert(Pt::rt[i-1],Pt::rt[i],1,m,f[i]);else Pt::rt[i]=Pt::rt[i-1];
    	while(q--){
    		int l=read()^(last*tp),r=read()^(last*tp);
    		int del=Pt::query(Pt::rt[r],1,m,l,r)-Pt::query(Pt::rt[l-1],1,m,l,r);
    		cout<<(last=(n-(r-l+1)+del))<<'
    ';
    	}
    }
    
  • 相关阅读:
    用PHP如何打造一个高可用高性能的网站
    php 数据批量插入mysql和mysql类
    PHP8新特性
    php 爬取抖音评论数据
    Python学习笔记之7.5
    mysql基本概念
    开发google插件
    php curl 重定向 cookie问题
    git 入门
    git对已经提交过的文件添加到.gitignore
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328610.html
Copyright © 2011-2022 走看看