【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 #include<algorithm>
  6 #include<cctype>
  7
  8 using namespace std;
  9
 10 const int Maxn=200020;
 11 const int logn=21;
 12
 13 int a[Maxn],b[Maxn],ntr[Maxn];
 14 int n,m,k,type;
 15
 16 template<typename Q> void gt(Q&x) {
 17     static char c;
 18     static bool f;
 19     for(f=0;c=getchar(),!isdigit(c);) if(c==‘-‘) f=1;
 20     for(x=0;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
 21     f && (x=-x);
 22 }
 23
 24 struct PST {
 25     int seq[Maxn];
 26
 27     struct Node{
 28         Node *l,*r;
 29         int sz;
 30     }pool[Maxn*logn],*pis,*root[Maxn],*null;
 31
 32     void build(Node*&o,Node *p,int l,int r,int rk) {
 33         o=pis++;
 34         *o=*p;
 35         o->sz++;
 36         if(l==r) return;
 37         int mid=(l+r)>>1;
 38         if(rk<=mid) build(o->l,p->l,l,mid,rk);
 39         else build(o->r,p->r,mid+1,r,rk);
 40     }
 41
 42     void init() {
 43         pis=pool;
 44         memcpy(seq,ntr,sizeof seq);
 45         sort(seq+1,seq+m+1);
 46         null=pis++;
 47         null->l=null->r=null;
 48         null->sz=0;
 49         root[0]=null;
 50         for(int i=1;i<=m;i++) {
 51             build(root[i],root[i-1],1,m+2,ntr[i]);
 52         }
 53     }
 54
 55     int query(Node*L,Node*R,int l,int r,int lft,int rgt) {
 56         if(lft<=l && r<=rgt) return R->sz - L->sz;
 57         int mid=(l+r)>>1;
 58         int ans=0;
 59         if(lft<=mid) ans+=query(L->l,R->l,l,mid,lft,rgt);
 60         if(mid<rgt) ans+=query(L->r,R->r,mid+1,r,lft,rgt);
 61         return ans;
 62     }
 63
 64     int query(int l,int r,int x) {
 65         return query(root[l-1],root[r],1,m+2,1,x);
 66     }
 67 }pst;
 68
 69 int ch[Maxn*2][2],w[Maxn*2],mn[Maxn*2],p[Maxn*2],flip[Maxn*2];
 70
 71 #define l ch[x][0]
 72 #define r ch[x][1]
 73 void update(int x) {
 74     mn[x]=x;
 75     if(w[mn[l]]<w[mn[x]]) mn[x]=mn[l];
 76     if(w[mn[r]]<w[mn[x]]) mn[x]=mn[r];
 77 }
 78
 79 void down(int x) {
 80     if(flip[x]) {
 81         swap(l,r);
 82         flip[l]^=1;
 83         flip[r]^=1;
 84         flip[x]^=1;
 85     }
 86 }
 87 #undef l
 88 #undef r
 89
 90 bool isroot(int x) {
 91     return ch[p[x]][0]!=x && ch[p[x]][1]!=x;
 92 }
 93
 94 void rotate(int x) {
 95     int y=p[x],z=p[y];
 96     if(!isroot(y)) ch[z][ch[z][1]==y]=x;
 97     int l=ch[y][1]==x,r=l^1;
 98     p[x]=z;
 99     p[y]=x;
100     p[ch[x][r]]=y;
101
102     ch[y][l]=ch[x][r];
103     ch[x][r]=y;
104
105     update(y);
106 //    update(x);
107 }
108
109 void splay(int x) {
110     static int stk[Maxn],top;
111     stk[top=1]=x;
112     for(int t=x;!isroot(t);t=p[t]) stk[++top]=p[t];
113     while(top) down(stk[top--]);
114
115     for(;!isroot(x);) {
116         int y=p[x],z=p[y];
117         if(!isroot(y)) {
118             if( (ch[y][0]==x)^(ch[z][0]==y) )rotate(x);
119             rotate(y);
120         }
121         rotate(x);
122     }
123     update(x);
124 }
125
126 void access(int x) {
127     for(int t=0;x;x=p[t=x]) {
128         splay(x);
129         ch[x][1]=t;
130         update(x);
131     }
132 }
133 void newroot(int x) {
134     access(x);
135     splay(x);
136     flip[x]^=1;
137 }
138
139 void Link(int x,int y) {
140     newroot(x);
141     p[x]=y;
142 }
143
144 void Cut(int x,int y) {
145     newroot(y);
146     access(x);
147     splay(x);
148     if(ch[x][0]==y) {
149         ch[x][0]=0;
150         p[y]=0;
151         update(x);
152     }
153 }
154
155 int getroot(int x) {
156     for(access(x),splay(x);ch[x][0];x=ch[x][0]);
157     return x;
158 }
159
160 const int INF=0x3f3f3f3f;
161
162 void init() {
163     scanf("%d%d%d%d",&n,&m,&k,&type);
164     for(int i=0;i<=n;i++) {
165         w[i]=INF;
166         mn[i]=i;
167     }
168     for(int x,y,i=1;i<=m;i++) {
169 //        scanf("%d%d",a+i,b+i);
170         gt(a[i]),gt(b[i]);
171         x=a[i],y=b[i];
172         if(x==y) {
173             ntr[i]=i;
174             continue;
175         }
176         if(getroot(x)==getroot(y)) {
177             newroot(y);
178             access(x);
179             splay(x);
180             int t=mn[x];
181             ntr[i]=w[t];
182             Cut(t,a[w[t]]);
183 //            Cut(t,b[w[t]]);
184         }
185         mn[i+n]=i+n;
186         w[i+n]=i;
187         Link(x,i+n);
188         Link(y,i+n);
189     }
190     for(int i=1;i<=m;i++) ntr[i]+=2;
191     pst.init();
192 }
193
194 void work() {
195     for(int l,r,last_ans=0;k--;) {
196 //        scanf("%d%d",&l,&r);
197         gt(l),gt(r);
198         if(type) l^=last_ans,r^=last_ans;
199
200         last_ans=n-pst.query(l,r,l+1);
201         printf("%d\n",last_ans);
202     }
203 }
204
205 void PST_test() {
206     scanf("%d",&m);
207     for(int i=1;i<=m;i++) {
208         scanf("%d",ntr+i);
209     }
210     for(int i=1;i<=m;i++) ntr[i]+=2;
211     pst.init();
212     for(scanf("%d",&k);k--;) {
213         int x,y,w;
214         scanf("%d%d%d",&x,&y,&w);w++;
215         printf("%d\n",pst.query(x,y,w));
216     }
217 }
218
219 int main() {
220 #ifdef DEBUG
221     freopen("in.txt","r",stdin);
222 //    freopen("out.txt","w",stdout);
223 #endif
224
225 //    PST_test();return 0;
226
227     init();
228     work();
229
230     return 0;
231 }

时间: 2024-08-06 23:18:05

【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

[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[max

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$数组有什么用呢,我

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>