bzoj4399 魔法少女LJJ
Description
在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了
LJJ感叹道“这里真是个迷人的绿色世界,空气清新、淡雅,到处散发着醉人的奶浆味;小猴在枝头悠来荡去,好不自在;各式各样的鲜花争相开放,各种树枝的枝头挂满沉甸甸的野果;鸟儿的歌声婉转动听,小河里飘着落下的花瓣真是人间仙境”
SHY觉得LJJ还是太naive,一天,SHY带着自己心爱的图找到LJJ,对LJJ说:“既然你已经见识过动态树,动态仙人掌了,那么今天就来见识一下动态图吧”
LJJ:“要支持什么操作?”
SHY:“
1.新建一个节点,权值为x。
2.连接两个节点。
3.将一个节点a所属于的联通快内权值小于x的所有节点权值变成x。
4.将一个节点a所属于的联通快内权值大于x的所有节点权值变成x。
5.询问一个节点a所属于的联通块内的第k小的权值是多少。
6.询问一个节点a所属联通快内所有节点权值之积与另一个节点b所属联通快内所有节点权值之积的大小。
7.询问a所在联通快内节点的数量
8.若两个节点a,b直接相连,将这条边断开。
9.若节点a存在,将这个点删去。
”
LJJ:“我可以离线吗?”
SHY:“可以,每次操作是不加密的,”
LJJ:“我可以暴力吗?”
SHY:“自重”
LJJ很郁闷,你能帮帮他吗
Input
第一行有一个正整数m,表示操作个数。
接下来m行,每行先给出1个正整数c。
若c=1,之后一个正整数x,表示新建一个权值为x的节点,并且节点编号为n+1(当前有n个节点)。
若c=2,之后两个正整数a,b,表示在a,b之间连接一条边。
若c=3,之后两个正整数a,x,表示a联通快内原本权值小于x的节点全部变成x。
若c=4,之后两个正整数a,x,表示a联通快内原本权值大于x的节点全部变成x。
若c=5,之后两个正整数a,k,表示询问a所属于的联通块内的第k小的权值是多少。
若c=6,之后两个正整数a,b,表示询问a所属联通快内所有节点权值之积与b所属联通快内所有节点权值之积的大小,
若a所属联通快内所有节点权值之积大于b所属联通快内所有节点权值之积,输出1,否则为0。
若c=7,之后一个正整数a,表示询问a所在联通块大小
若c=8,之后两个正整数a,b,表示断开a,b所连接的边。
若c=9,之后一个正整数a,表示断开a点的所有连边
具体输出格式见样例
Output
Sample Input
1 2
1 3
1 4
1 5
1 6
2 1 2
2 2 3
2 3 4
2 4 5
9 1
3 2 5
5 3 4
Sample Output
HINT
对100%的数据 0<=m<=400000,c<=7,所有出现的数均<=1000000000,所有出现的点保证存在
【HINT】请认真阅读题面
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define R register int 4 #define rep(i, a, b) for (R i = a; i <= b; i++) 5 #define Rep(i, a, b) for (R i = a; i >= b; i--) 6 #define ms(i, a) memset(a, i, sizeof(a)) 7 #define gc() getchar() 8 #define mid (l + r) / 2 9 template <class T> 10 void read(T &x) 11 { 12 x = 0; 13 char c = 0; 14 int w = 0; 15 while (!isdigit(c)) 16 w += c == '-', c = gc(); 17 while (isdigit(c)) 18 x = x * 10 + (c ^ 48), c = gc(); 19 if (w) 20 x = -x; 21 } 22 int const N = 400000 + 3; 23 24 struct query 25 { 26 int x, a, b; 27 } q[N]; 28 29 struct node 30 { 31 int s; 32 double lg; 33 node *lc, *rc; 34 }; 35 int a[N], sum, cnt, m, n, f[N]; 36 node *rt[N]; 37 set<int> se; 38 map<int, int> mat; 39 int gf(int x) { return x == f[x] ? x : f[x] = gf(f[x]); } 40 void pushup(node *x) 41 { 42 x->s=x->lg=0; 43 if (x->lc) 44 x->s += x->lc->s, x->lg += x->lc->lg; 45 if (x->rc) 46 x->s += x->rc->s, x->lg += x->rc->lg; 47 } 48 void update(node *&x, int l, int r, int p, int num) 49 { 50 if (!x) 51 x = new node(); 52 if (l == r) 53 { 54 x->s += num; 55 x->lg += log10(a[p]) * num; 56 return; 57 } 58 if (p <= mid) 59 update(x->lc, l, mid, p, num); 60 else 61 update(x->rc, mid + 1, r, p, num); 62 pushup(x); 63 } 64 node *merge(node *x, node *y) 65 { 66 if (!x && y) 67 return y; 68 if (x && !y) 69 return x; 70 if (!x && !y) 71 return 0; 72 x->lc = merge(x->lc, y->lc); 73 x->rc = merge(x->rc, y->rc); 74 x->s += y->s; 75 x->lg += y->lg; 76 return x; 77 } 78 int insert(node *&x, int l, int r, int ll, int rr) 79 { 80 if(!x) return 0; 81 if (ll > rr) 82 return 0; 83 if (ll <= l && r <= rr) 84 { 85 int t = x->s; 86 delete (x); 87 x = 0; 88 return t; 89 } 90 int t = 0; 91 if (ll <= mid) 92 t += insert(x->lc, l, mid, ll, rr); 93 if (rr > mid) 94 t += insert(x->rc, mid + 1, r, ll, rr); 95 pushup(x); 96 return t; 97 } 98 int Q(node *x, int l, int r, int p) 99 { 100 if (l == r) 101 return a[l]; 102 int num = x->lc ? x->lc->s : 0; 103 if (p <= num) 104 return Q(x->lc, l, mid, p); 105 else 106 return Q(x->rc, mid + 1, r, p - num); 107 } 108 int main() 109 { 110 read(m); 111 rep(i, 1, m) 112 { 113 read(q[i].x); 114 if (q[i].x == 1 || q[i].x == 7 || q[i].x == 9) 115 read(q[i].a); 116 else 117 read(q[i].a), read(q[i].b); 118 if (q[i].x == 1) 119 se.insert(q[i].a); 120 else if (q[i].x == 3 || q[i].x == 4) 121 se.insert(q[i].b); 122 } 123 for (set<int>::iterator p = se.begin(); p != se.end(); p++) 124 a[++n] = *p, mat[*p] = n; 125 rep(i, 1, n) f[i] = i; 126 rep(i, 1, m) 127 { 128 if (q[i].x == 1) 129 { 130 ++cnt; 131 update(rt[cnt], 1, n, mat[q[i].a], 1); 132 } 133 if (q[i].x == 2) 134 { 135 int fx = gf(q[i].a); 136 int fy = gf(q[i].b); 137 if (fx != fy) 138 { 139 f[fy] = fx; 140 rt[fx] = merge(rt[fx], rt[fy]); 141 } 142 } 143 if (q[i].x == 3) 144 { 145 int fx = gf(q[i].a); 146 int num = insert(rt[fx], 1, n, 1, mat[q[i].b] - 1); 147 update(rt[fx], 1, n, mat[q[i].b], num); 148 } 149 if (q[i].x == 4) 150 { 151 int fx = gf(q[i].a); 152 int num = insert(rt[fx], 1, n, mat[q[i].b] + 1, n); 153 update(rt[fx], 1, n, mat[q[i].b], num); 154 } 155 if (q[i].x == 5) 156 { 157 int fx = gf(q[i].a); 158 printf("%d\n", Q(rt[fx], 1, n, q[i].b)); 159 } 160 if (q[i].x == 6) 161 { 162 int fx = gf(q[i].a); 163 int fy = gf(q[i].b); 164 puts(rt[fx]->lg > rt[fy]->lg ? "1" : "0"); 165 } 166 if (q[i].x == 7) 167 { 168 int fx = gf(q[i].a); 169 printf("%d\n", rt[fx]->s); 170 } 171 } 172 return 0; 173 }