隐藏
「bzoj3514」GERALD07加强版 - LCT+贪心 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「bzoj3514」GERALD07加强版 - LCT+贪心

题目大意

    $N$个点$M$条边的无向图,询问保留图中编号在$[l,r]$的边的时候图中的联通块个数。


题目分析

这道题一样的技巧。
记录一下每条边$i$把哪条边弹出去了,把编号放进$del[i]$,如果没有弹出去,记录为$0$。
每个询问,答案就是$n$减去$l\sim r$中$del$小于$l$的边的条数(注意$0$也小于$l$)。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include<bits/stdc++.h>

using namespace std;

inline int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(!isdigit(x)) {if(x=='-')bj=-1;x=getchar();}
while(isdigit(x)) {num=num*10+x-'0';x=getchar();}
return num*bj;
}

const int maxn=400005;

int n,m,q,type,tot=0,del[maxn];

struct Tree {
int child[2],fa;
bool rev;
int val,minid;
Tree(int v=0,int id=0):val(v),minid(id) {child[0]=child[1]=fa=rev=0;}
};

struct Link_Cut_Tree {
Tree tree[maxn];
int top,S[maxn];
#define fa(x) tree[x].fa
#define ls(x) tree[x].child[0]
#define rs(x) tree[x].child[1]
#define rev(x) tree[x].rev
bool isroot(int x) {return ls(fa(x))!=x&&rs(fa(x))!=x;}
bool checkson(int x) {return rs(fa(x))==x;}
void reverse(int x) {swap(ls(x),rs(x));rev(x)^=1;}
void push_down(int x) {
if(!rev(x))return;
reverse(ls(x)),reverse(rs(x));
rev(x)=0;
}
void push_up(int x) {
tree[x].minid=x;
if(tree[tree[ls(x)].minid].val<tree[tree[x].minid].val)tree[x].minid=tree[ls(x)].minid;
if(tree[tree[rs(x)].minid].val<tree[tree[x].minid].val)tree[x].minid=tree[rs(x)].minid;
}
void rotate(int x) {
int f=fa(x),g=fa(f),side=checkson(x);
if(!isroot(f))tree[g].child[checkson(f)]=x;
tree[f].child[side]=tree[x].child[!side],fa(tree[f].child[side])=f;
fa(f)=x,tree[x].child[!side]=f;
fa(x)=g;
push_up(f),push_up(x);
}
void splay(int x) {
S[++top]=x;
for(int i=x; !isroot(i); i=fa(i))S[++top]=fa(i);
while(top)push_down(S[top--]);
for(int f; !isroot(x); rotate(x)) {
f=fa(x);
if(!isroot(f))rotate(checkson(x)==checkson(f)?f:x);
}
}
void access(int x) {
for(int son=0; x; son=x,x=fa(x)) {
splay(x);
rs(x)=son;
push_up(x);
}
}
void make_root(int x) {access(x);splay(x);reverse(x);}
void split(int x,int y) {make_root(x);access(y);splay(y);}
void link(int x,int y) {make_root(x);fa(x)=y;} //y->x
void cut(int x,int y) {split(x,y);ls(y)=fa(x)=0;}
int get_root(int x) {
access(x);
splay(x);
while(ls(x))x=ls(x);
return x;
}
} lct;

struct President_Tree {
struct Tree {
int ls,rs,size;
} tree[maxn*20];
int size;
#define mid ((left+right)>>1)
void insert(int &now,int pre,int left,int right,int val) {
tree[now=++size]=tree[pre];
tree[now].size++;
if(left==right)return;
if(val<=mid)insert(tree[now].ls,tree[pre].ls,left,mid,val);
else insert(tree[now].rs,tree[pre].rs,mid+1,right,val);
}
int query(int left,int right,int lt,int rt,int tar) {
if(right==tar)return tree[rt].size-tree[lt].size;
if(tar<=mid)return query(left,mid,tree[lt].ls,tree[rt].ls,tar);
return tree[tree[rt].ls].size-tree[tree[lt].ls].size+query(mid+1,right,tree[lt].rs,tree[rt].rs,tar);
}
} pt;

struct Edge {
int from,to;
Edge(int x=0,int y=0):from(x),to(y) {}
} edges[maxn];

int root[maxn],ans=0;

int main() {
n=Get_Int();
m=Get_Int();
q=Get_Int();
type=Get_Int();
for(int i=0; i<=n; i++)lct.tree[i]=Tree(INT_MAX,i);
for(int i=1; i<=m; i++) {
int x=Get_Int(),y=Get_Int();
edges[i]=Edge(x,y);
}
tot=n;
for(int i=1; i<=m; i++) {
Edge &e=edges[i];
if(e.from==e.to) {del[i]=i;continue;}
if(lct.get_root(e.from)==lct.get_root(e.to)) {
lct.split(e.from,e.to);
int id=lct.tree[e.to].minid;
del[i]=lct.tree[id].val;
lct.cut(edges[del[i]].from,id),lct.cut(id,edges[del[i]].to);
}
tot++;
lct.tree[tot]=Tree(i,tot);
lct.link(e.from,tot),lct.link(tot,e.to);
}
for(int i=1; i<=m; i++)pt.insert(root[i],root[i-1],0,m,del[i]);
for(int i=1; i<=q; i++) {
int l=Get_Int()^(type*ans),r=Get_Int()^(type*ans);
printf("%d\n",ans=n-pt.query(0,m,root[l-1],root[r],l-1));
}
return 0;
}
姥爷们赏瓶冰阔落吧~