[bzoj3514]: Codechef MARCH14 GERALD07加强版

  跪了半天题解才会。。TAT

http://hzwer.com/4358.html

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 using namespace std;
  5 const int maxn=200233<<1;
  6 const int inf=1000023333;
  7 struct zs{
  8     int u,v;
  9 }e[200233];
 10 int ch[maxn][2],fa[maxn],mnpos[maxn],st[maxn],top;
 11 bool rev[maxn],ty;
 12 int lc[200233*30],rc[200233*30],sz[200233*30],rt[200233],ntr[200233];
 13 int i,j,k,n,m,x,y,l,r,K,tot,ans,a;
 14
 15 int ra;char rx;
 16 inline int read(){
 17     ra=0,rx=getchar();
 18     while(rx<‘0‘||rx>‘9‘)rx=getchar();
 19     while(rx>=‘0‘&&rx<=‘9‘)ra*=10,ra+=rx-48,rx=getchar();return ra;
 20 }
 21 inline int min(int a,int b){return a<b?a:b;}
 22 inline bool isrt(int x){
 23     return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
 24 }
 25 inline void pushdown(int x){
 26     if(!rev[x])return;
 27
 28     int l=ch[x][0],r=ch[x][1];
 29     if(l)rev[l]^=1;if(r)rev[r]^=1;
 30     swap(ch[x][0],ch[x][1]),rev[x]=0;
 31 }
 32 inline void upd(int x){
 33     mnpos[x]=min(x<=m?x:inf,min(mnpos[ch[x][0]],mnpos[ch[x][1]]));
 34 }
 35 inline void rotate(int x){
 36     int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1;
 37     if(!isrt(f))ch[gfa][ch[gfa][1]==f]=x;
 38     fa[ch[f][l]=ch[x][r]]=f,fa[fa[ch[x][r]=f]=x]=gfa;
 39     mnpos[x]=mnpos[f],upd(f);
 40 }
 41 inline void splay(int x){
 42     int f=x,gfa;
 43     for(st[top=1]=f;!isrt(f);st[++top]=(f=fa[f]));
 44     while(top)pushdown(st[top--]);
 45     while(!isrt(x)){
 46         f=fa[x],gfa=fa[f];
 47         if(!isrt(f))
 48             rotate(((ch[f][1]==x)^(ch[gfa][1]==f))?x:f);
 49         rotate(x);
 50     }
 51 }
 52 inline void access(int x){
 53     for(int rc=0;x;rc=x,x=fa[x])
 54         splay(x),ch[x][1]=rc,upd(x);
 55 }
 56 inline void makert(int x){
 57     access(x),splay(x),rev[x]^=1;
 58 }
 59 inline void link(int x,int y){
 60     makert(x),fa[x]=y;
 61 }
 62 inline void cut(int x,int y){
 63     makert(x),access(y),splay(y),fa[x]=ch[y][0]=0;
 64 }
 65 inline int getfa(int x){
 66     for(access(x),splay(x);ch[x][0];x=ch[x][0]);
 67     return x;
 68 }
 69
 70 inline void insert(int pre,int &x,int a,int b,int v){
 71     sz[x=++tot]=sz[pre]+1;
 72     if(a==b)return;
 73     int mid=(a+b)>>1;
 74     if(v<=mid)rc[x]=rc[pre],insert(lc[pre],lc[x],a,mid,v);
 75     else lc[x]=lc[pre],insert(rc[pre],rc[x],mid+1,b,v);
 76 }
 77 inline int query(int pre,int x,int a,int b,int d){
 78     if(b<=d||!x)return sz[x]-sz[pre];
 79     int mid=(a+b)>>1;
 80     if(d<=mid)return query(lc[pre],lc[x],a,mid,d);
 81     else return sz[lc[x]]-sz[lc[pre]]+query(rc[pre],rc[x],mid+1,b,d);
 82 }
 83 int main(){
 84     n=read(),m=read(),K=read(),ty=read();
 85     mnpos[0]=inf;
 86     for(i=1;i<=m;i++)mnpos[i]=i;for(i=m+1;i<=n+m;i++)mnpos[i]=inf;
 87
 88     for(i=1;i<=m;i++){
 89         e[i].u=x=read(),e[i].v=y=read();
 90         x+=m,y+=m;
 91         if(x!=y){
 92             if(getfa(x)==getfa(y)){
 93                 makert(x),access(y),splay(y),ntr[i]=a=mnpos[y];
 94                 cut(e[a].u+m,a),cut(a,e[a].v+m);
 95             }
 96             link(x,i),link(i,y);
 97         }else ntr[i]=i;
 98         insert(rt[i-1],rt[i],0,m,ntr[i]);
 99 //        printf("  %d  %d\n",i,ntr[i]);
100     }
101     while(K--){
102         l=read()^(ty?ans:0),r=read()^(ty?ans:0);
103         ans=n-query(rt[l-1],rt[r],0,m,l-1);
104         printf("%d\n",ans);
105     }
106     return 0;
107 }

时间: 2024-10-12 10:29:10

[bzoj3514]: Codechef MARCH14 GERALD07加强版的相关文章

[BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)

3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2177  Solved: 834[Submit][Status][Discuss] Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M行,代表图中的每条边.接下来K行,每行两个整数L

【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版

3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2023  Solved: 778[Submit][Status][Discuss] Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来M行,代表图中的每条边. 接下来K行,每行两个整

BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT

欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N,M,Q<=200000 题解 http://hzwer.com/4358.html 这题hzwer还是写的很好的-- 代码 #include <cstring> #include <cstdio> #include <cstdlib> #include <al

BZOJ 3514: Codechef MARCH14 GERALD07加强版

3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1356  Solved: 514[Submit][Status][Discuss] Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M行,代表图中的每条边.接下来K行,每行两个整数L

BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )

从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献, 答案就是N-x. 用LCT维护加边, 可持久化线段树维护询问. O(NlogN) ------------------------------------------------------------------------------------ #include<cstdio> #inc

【BZOJ3514】Codechef MARCH14 GERALD07加强版(LCT)

题意:N个点M条边的无向图,q次询问保留图中编号在[l,r]的边的时候图中的联通块个数. 询问加密,强制在线 n,m,q<=200000 题意:RYZ作业 以下转载自hzwer http://hzwer.com/4358.html 本人实力有限难以清晰描述 有一个比较猎奇的做法:首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr[i] = 0;这个显然是可以用LCT来弄的

【bzoj3514】 Codechef MARCH14 GERALD07加强版

http://www.lydsy.com/JudgeOnline/problem.php?id=3514 (题目链接) 题意 给出$n$个点$m$条边的无向图,询问保留图中编号在$[l,r]$的边的时候图中的连通块的个数. Solution 将边的编号作为权值用LCT维护一个最大生成树,同时记录一下加入当前边$i$会把哪一条原本在生成树中的边踢掉,记作$ntr[i]$.如果不会踢掉任意一条边,那么$ntr[i]=0$.如果$i$是自环,那么$ntr[i]=i$. 求出$ntr$数组有什么用呢,我

【bzoj3514】Codechef MARCH14 GERALD07加强版

hzwer上少有的几道需要建一下模的 要不是有这么几道题 我都觉得lct只会考裸题了呢 题解看hzwer吧 http://hzwer.com/4358.html 唯一蛋疼的就是为了处理0这个呵呵的位置,和严格小于,我把ntr数组全部+2,然后l+1,这样建树的时候就要写m+2了= =好蛋疼 1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #in

bzoj 3514 Codechef MARCH14 GERALD07加强版 主席树+LCT

题面 题目传送门 解法 思路很妙 参见hzwer的题解 主席树+LCT--真是个毒瘤的组合 时间复杂度:\(O((m+q)\ log\ m)\) 代码 #include <bits/stdc++.h> #define N 400010 using namespace std; template <typename node> void chkmax(node &x, node y) {x = max(x, y);} template <typename node>