菜鸡刷题记录

 [题号:题解]


 

1008:简单排列组合

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 const ll MOD = (ll)1e5 + 3;
 6 ll n, m;
 7 
 8 ll qmod(ll base, ll n)
 9 {
10     ll res = 1;
11     while (n)
12     {
13         if (n & 1) res = res * base % MOD;
14         base = base * base % MOD;
15         n >>= 1;
16     }
17     return res; 
18 }
19 
20 int main()
21 {
22     while (scanf("%lld%lld", &m, &n) != EOF)
23         printf("%lld\n", (qmod(m, n) - (m % MOD * qmod(m - 1, n - 1) % MOD) + MOD) % MOD);
24     return 0;
25 }
View Code

1012:BIT维护后缀最大

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1000010
 5 #define ll long long
 6 int m, n; ll D;
 7 
 8 struct BIT
 9 {
10     ll a[N];
11     void Init() { memset(a, 0, sizeof a); } 
12     void update(int x, ll val)
13     {
14         for (; x; x -= x & -x)
15             a[x] = max(a[x], val);
16     }
17     ll query(int x)
18     {
19         ll res = 0;
20         for (; x <= n; x += x & -x)   
21             res = max(res, a[x]); 
22         return res; 
23     }
24 }bit;
25 
26 void Run()
27 {
28     scanf("%d%lld", &m, &D);
29     bit.Init();
30     char op; ll x, lastans = 0; n = 0;
31     for (int i = 1; i <= m; ++i)
32     {
33         scanf(" %c%lld", &op, &x);
34         if (op == 'Q') printf("%lld\n", lastans = bit.query(n - x + 1));
35         else bit.update(++n, (x + lastans) % D);
36     }
37 }
38 
39 int main()
40 {
41     #ifdef LOCAL
42         freopen("Test.in", "r", stdin); 
43     #endif 
44 
45     Run();
46     return 0;
47 
48 }
View Code

1051:Tarjan缩点

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define pii pair <int, int>
 5 #define N 10010
 6 
 7 int n, m;
 8 map <pii, bool> mp;
 9 vector <int> G[N];
10 int Low[N], DFN[N], Stack[N], Belong[N], sze[N], degree[N], cnt, sec, top;
11 bool Instack[N];
12 
13 void Tarjan(int u)
14 {
15     Low[u] = DFN[u] = ++cnt;
16     Stack[top++] = u;
17     Instack[u] = 1;
18     for (int i = 0, len = G[u].size(); i < len; ++i)
19     {
20         int v = G[u][i];
21         if (!DFN[v])
22         {
23             Tarjan(v);
24             Low[u] = min(Low[u], Low[v]);
25         }
26         else if (Instack[v]) Low[u] = min(Low[u], DFN[v]);
27     }
28     if (DFN[u] == Low[u]) 
29     {
30         ++sec; int v;
31         do
32         {
33             v = Stack[--top]; 
34             Instack[v] = 0;
35             Belong[v] = sec;
36             ++sze[sec];    
37         } while (v != u);
38     }
39 }
40 
41 int Run()
42 {
43     for (int i = 1; i <= n; ++i) if (!DFN[i])
44         Tarjan(i);
45     for (int u = 1; u <= n; ++u)
46     {
47         for (int i = 0, len = G[u].size(); i < len; ++i)
48         {
49             int v = G[u][i];
50             if (Belong[v] != Belong[u])
51             ++degree[Belong[u]];
52         }
53     }
54     int flag = 0;
55     for (int i = 1; i <= sec; ++i) if (!degree[i]) ++flag; 
56     if (flag > 1) return 0;
57     for (int i = 1; i <= sec; ++i) if (!degree[i])
58         return sze[i];
59     return 0;
60 }
61 
62 int main()
63 {
64     while (scanf("%d%d", &n, &m) != EOF)
65     {
66         for (int i = 1; i <= n; ++i) G[i].clear();
67         mp.clear(); cnt = 0; sec = 0; top = 0;
68         memset(sze, 0, sizeof sze);
69         memset(degree, 0, sizeof degree);    
70         for (int i = 1, u, v; i <= m; ++i)
71         {
72             scanf("%d%d", &u, &v);
73             if(mp.find(pii(u, v)) != mp.end()) continue;
74             G[u].push_back(v);
75             mp[pii(u, v)] = 1;
76         }
77         printf("%d\n", Run());
78     }
79     return 0;
80 }
View Code

1086:树分块

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1010
 5 
 6 int n, b;
 7 vector <int> G[N];
 8 stack <int> sta;
 9 int Belong[N], sze[N], cap[N], cnt;
10 
11 void DFS(int u, int fa)
12 {
13     sze[u] = 0;
14     sta.push(u); 
15     for (int i = 0, v, len = G[u].size(); i < len; ++i) if ((v = G[u][i]) != fa)
16     {
17         DFS(v, u);
18         sze[u] += sze[v];
19         if (sze[u] >= b) 
20         {
21             sze[u] = 0;
22             cap[++cnt] = u;
23             while (!sta.empty() && sta.top() != u) { Belong[sta.top()] = cnt; sta.pop(); }
24         }
25     } 
26     ++sze[u];
27 }
28 
29 void DFS2(int u, int fa, int sp)
30 {
31     Belong[u] ? sp = Belong[u] : Belong[u] = sp;
32     for (int i = 0, v, len = G[u].size(); i < len; ++i) if ((v = G[u][i]) != fa)
33         DFS2(v, u, sp);
34 }
35 
36 void Run()
37 {
38     while (scanf("%d%d", &n, &b) != EOF)
39     {
40         if (n < b) { puts("0"); continue; }
41         for (int i = 1; i <= n; ++i) G[i].clear();
42         while (!sta.empty()) sta.pop();
43         cnt = 0;
44         memset(Belong, 0, sizeof Belong);
45         for (int i = 1, u, v; i < n; ++i)
46         {
47             scanf("%d%d", &u, &v);
48             G[u].push_back(v);
49             G[v].push_back(u);
50         }
51         DFS(1, 1); DFS2(1, 1, cnt);
52         if (!cnt) cap[cnt = 1] = 1;
53         printf("%d\n", cnt);
54         for (int i = 1; i <= n; ++i) printf("%d%c", Belong[i], " \n"[i == n]);
55         for (int i = 1; i <= cnt; ++i) printf("%d%c", cap[i], " \n"[i == cnt]);
56     }
57 }
58 
59 int main()
60 {
61     #ifdef LOCAL
62         freopen("Test.in", "r", stdin);
63     #endif 
64 
65     Run();
66     return 0;
67 
68 }
View Code

1216:模拟+优先队列,主要不要暴力枚举时间

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1501000
 5 #define ll long long
 6 struct node
 7 {
 8     int id,  pri; ll arrive, time;
 9     int scan() { return scanf("%d%lld%lld%d", &id, &arrive, &time, &pri); }
10     void output(ll now) { printf("%d %lld\n", id, now); }
11     bool operator < (const node &r) const
12     {
13         return pri < r.pri || (pri == r.pri && id > r.id); 
14     }
15 }arr[N];
16 
17 priority_queue <node> q;
18 
19 int main()
20 {
21     int n;
22     for (n = 1; ; ++n) if (arr[n].scan() == EOF) break; --n;
23     while (!q.empty()) q.pop(); 
24     ll t = 0;
25     for (int i = 1; i <= n; ++i)
26     {
27         if (q.empty())
28         {
29             q.push(arr[i]);
30             t = max(t, arr[i].arrive);
31         }
32         else
33         {
34             node tmp = q.top(); 
35             while (t + tmp.time <= arr[i].arrive)
36             {
37                 t += tmp.time;
38                 q.pop();
39                 tmp.output(t);
40                 if (q.empty()) break;
41                 tmp = q.top();
42             }
43             if (t < arr[i].arrive && !q.empty())
44             {
45                 ll gap = arr[i].arrive - t;
46                 tmp = q.top(); q.pop();
47                 tmp.time -= gap;
48                 q.push(tmp);
49                 t = arr[i].arrive; 
50             }
51             q.push(arr[i]);
52             t = max(t, arr[i].arrive);
53         }
54     }
55     while (!q.empty())
56     {
57         node tmp = q.top(); q.pop();
58         t += tmp.time;    
59         tmp.output(t); 
60     }
61     return 0;
62 }
View Code

1635:差分+坑 有重复

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 10100
 5 #define pii pair <int, int>
 6 int n, i, h, q;
 7 int ans[N];
 8 map <pii, bool> mp;
 9 
10 int main()
11 {
12     while (scanf("%d%d%d%d", &n, &i, &h, &q) != EOF)
13     {
14         memset(ans, 0, sizeof ans);
15         mp.clear();
16         for (int i = 1, l, r; i <= q; ++i)
17         {
18             scanf("%d%d", &l, &r);
19             if (l > r) swap(l, r);
20             if (mp.find(pii(l, r)) != mp.end()) continue;
21             mp[pii(l, r)] = 1;
22             --ans[l + 1]; ++ans[r];
23         }
24         for (int i = 1; i <= n; ++i) ans[i] += ans[i - 1];
25         for (int i = 1; i <= n; ++i) printf("%d\n", h + ans[i]);
26     }
27     return 0;
28 }
View Code

1935:排序一维,树状数组一维

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 3000010 
 5 
 6 int n, q, m;
 7 int ans[N], brr[N];
 8 struct node
 9 {
10     // 0 insert
11     // 1 add
12     // 2 sub
13     int op, x, y, id; 
14     node() {}
15     node(int op, int x, int y, int id) : op(op), x(x), y(y), id(id) {}
16     bool operator < (const node &r) const
17     { 
18         return x == r.x ? id < r.id : x < r.x; 
19     }
20 }arr[N];
21 
22 struct BIT
23 {
24     int a[N]; 
25 
26     void Init()
27     {
28         memset(a, 0, sizeof a);
29     }
30 
31     void update(int x, int val)
32     {
33         while (x <= m)  
34         {
35             a[x] += val;
36             x += x & -x;
37         }
38     }
39 
40     int query(int x)
41     {
42         int res = 0;
43         while (x)
44         {
45             res += a[x];
46             x -= x & -x;
47         }
48         return res;
49     }
50 }bit;
51 
52 void Hash()
53 {
54     sort(brr + 1, brr + 1 + m);
55     int    tmp = unique(brr + 1, brr + 1 + m) - brr - 1; 
56     for (int i = 1; i <= m; ++i)
57         arr[i].y = lower_bound(brr + 1, brr + 1 + tmp, arr[i].y) - brr; 
58 }
59 
60 void Run()
61 {
62     while (scanf("%d%d", &n, &q) != EOF)
63     {
64         m = n;
65         for (int i = 1, x, y; i <= n; ++i)
66         {
67             scanf("%d%d", &x, &y);
68             arr[i] = node(0, x, y, 0); 
69             brr[i] = y; 
70         }
71         for (int i = 1, x[2], y[2]; i <= q; ++i)
72         {
73             for (int j = 0; j < 2; ++j) scanf("%d%d", x + j, y + j);
74             arr[++m] = node(1, x[1], y[1], i); brr[m] = y[1]; 
75             arr[++m] = node(1, x[0] - 1, y[0] - 1, i); brr[m] = y[0] - 1;
76             arr[++m] = node(-1, x[1], y[0] - 1, i); brr[m] = y[0] - 1;
77             arr[++m] = node(-1, x[0] - 1, y[1], i); brr[m] = y[1];
78         }
79         Hash();  
80         sort(arr + 1, arr + 1 + m);   
81         for (int i = 1; i <= m; ++i)
82         {
83             if (arr[i].id == 0) bit.update(arr[i].y, 1);
84             else
85                 ans[arr[i].id] += bit.query(arr[i].y) * arr[i].op;
86         }
87         for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]); 
88     }
89 }
90 
91 int main()
92 {
93     #ifdef LOCAL
94         freopen("Test.in", "r", stdin); 
95     #endif 
96 
97     Run();
98     return 0;
99 }
View Code

2014:虚树+DP

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define INF 0x3f3f3f3f3f3f3f3f
  6 #define N 1000010
  7 int n, q, k, a[N];
  8 
  9 struct Graph
 10 {
 11     struct node
 12     {
 13         int to, nx;
 14         node() {}
 15         node(int to, int nx) : to(to), nx(nx) {}
 16     }a[N << 1];
 17     int head[N], pos;
 18     void init() { memset(head, 0, sizeof head); pos = 0; }
 19     void add(int u, int v)
 20     {
 21         a[++pos] = node(v, head[u]); head[u] = pos;
 22         a[++pos] = node(u, head[v]); head[v] = pos;
 23     }
 24 }g[2];
 25 #define erp(id, u) for (int it = g[id].head[u], v = g[id].a[it].to; it; it = g[id].a[it].nx, v = g[id].a[it].to)
 26 
 27 int fa[N], son[N], top[N], p[N], cnt; ll deep[N], sze[N];
 28 void DFS(int u)       
 29 {
 30     sze[u] = 1;
 31     erp(0, u) if (v != fa[u]) 
 32     {
 33         fa[v] = u;
 34         deep[v] = deep[u] + 1;
 35         DFS(v); sze[u] += sze[v];
 36         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
 37     }
 38 }
 39 
 40 void getpos(int u, int sp)
 41 {
 42     top[u] = sp;
 43     p[u] = ++cnt;
 44     if (!son[u]) return;
 45     getpos(son[u], sp);
 46     erp(0, u) if (v != fa[u] && v != son[u]) 
 47         getpos(v, v);
 48 }     
 49 
 50 int querylca(int u, int v)
 51 {
 52     while (top[u] != top[v])
 53     {
 54         if (deep[top[u]] < deep[top[v]]) swap(u, v);
 55         u = fa[top[u]];
 56     }
 57     if (deep[u] > deep[v]) swap(u, v); 
 58     return u;
 59 }
 60 
 61 ll Max[N], Min[N], sum[N], res_Max, res_Min, res_sum; int vis[N]; 
 62 void dp(int u, int fa)
 63 {
 64     Max[u] = 0; Min[u] = INF; sum[u] = 0;
 65     sze[u] = vis[u];
 66     erp(1, u) if (v != fa)
 67         dp(v, u), sze[u] += sze[v]; 
 68     if (vis[u]) Max[u] = Min[u] = sum[u] = deep[u];  
 69     erp(1, u) if (v != fa)
 70     {
 71         sum[u] += sum[v];
 72         res_sum += (sum[v] - deep[u] * sze[v]) * (sze[u] - sze[v]); 
 73         if (Max[u]) res_Max = max(res_Max, Max[u] + Max[v] - 2 * deep[u]); 
 74         Max[u] = max(Max[u], Max[v]);
 75         if (Min[v] != INF) res_Min = min(res_Min, Min[u] + Min[v] - 2 * deep[u]);
 76         Min[u] = min(Min[u], Min[v]);
 77     }
 78     vis[u] = 0;  g[1].head[u] = 0; 
 79 }
 80 
 81 bool cmp(int a, int b) { return p[a] < p[b]; } 
 82 
 83 void init()
 84 {
 85     g[0].init(); g[1].init(); cnt = 0;
 86     memset(son, 0, sizeof son);
 87 }
 88 
 89 int stktop, stk[N];
 90 void Run()
 91 {
 92     while (scanf("%d", &n) != EOF)
 93     {
 94         init();
 95         for (int i = 1, u, v; i < n; ++i)
 96         {
 97             scanf("%d%d", &u, &v);
 98             g[0].add(u, v);
 99         } deep[1] = 1; DFS(1); getpos(1, 1);  
100         scanf("%d", &q);
101         for (int qq = 1; qq <= q; ++qq)
102         {
103             scanf("%d", &k);
104             for (int i = 1; i <= k; ++i) scanf("%d", a + i);
105             sort(a + 1, a + 1 + k, cmp); 
106             for (int i = 1; i <= k; ++i) vis[a[i]] = 1;  
107             stk[stktop = 1] = 1;  g[1].pos = 0;
108             for (int i = 1; i <= k; ++i)
109             {
110                 int lca = querylca(stk[stktop], a[i]);
111                 while (deep[lca] < deep[stk[stktop]])
112                 {
113                     if (deep[stk[stktop - 1]] <= deep[lca])
114                     {
115                         int last = stk[stktop--];
116                         if (stk[stktop] != lca) stk[++stktop] = lca; 
117                         g[1].add(last, lca);
118                         break;
119                     }
120                     g[1].add(stk[stktop - 1], stk[stktop]), --stktop;
121                 }
122                 if (stk[stktop] != a[i]) stk[++stktop] = a[i];
123             }
124             while (stktop > 1) g[1].add(stk[stktop - 1], stk[stktop]), --stktop;
125             res_Max = 0, res_Min = INF; res_sum = 0;   
126             dp(1, 1);
127             printf("%lld %lld %lld\n", res_sum, res_Min, res_Max);  
128         }
129     }
130 }
131 
132 int main()
133 {
134     #ifdef LOCAL
135         freopen("Test.in", "r", stdin);
136     #endif 
137 
138     Run();
139     return 0;
140 }
View Code

2056:特判+不要用iostream

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <cstdio>
 2 #define ull unsigned long long
 3 int t, a[10];
 4 ull res;
 5 
 6 int main()
 7 {
 8     scanf("%d", &t);
 9     while (t--)
10     {
11         for (int i = 1; i <= 8; ++i) scanf("%d", a + i);
12         scanf("%llu", &res); 
13         for (int i = 1; i <= 8; ++i) res += 1ll << a[i];
14         if (res == 0) res = -1;
15         if (res != -1) printf("%llu\n", res);    
16         else 
17         {
18             printf("%llu", res / 10);
19             puts("6");
20         }
21     }
22     return 0;
23 }
View Code

2120:带修改莫队

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 #define block 400
  6 
  7 int n, q, cnt_que, cnt_op;
  8 int arr[N], brr[N], ans[N], cnt[N * 10], res;
  9 
 10 struct QUE
 11 {
 12     int l, r, id, ti; 
 13     void scan(int id, int ti)
 14     {
 15         this->id = id;
 16         this->ti = ti;
 17         scanf("%d%d", &l, &r);
 18     }
 19     bool operator < (const QUE &r) const
 20     {
 21         int posl = l / block, posr = r.l / block;
 22         return posl == posr ? this->r < r.r : posl < posr; 
 23     }
 24 }que[N];
 25 
 26 struct OP
 27 {
 28     int pre, v, id;
 29     void scan()
 30     {
 31         scanf("%d%d", &id, &v);
 32         pre = brr[id];
 33         brr[id] = v;
 34     }
 35 }op[N];
 36 
 37 void update(int x, int val)
 38 {
 39     if (val == -1)
 40     {
 41         if (cnt[arr[x]] == 1) --res;
 42         --cnt[arr[x]];
 43     }
 44     else
 45     {
 46         ++cnt[arr[x]];
 47         if (cnt[arr[x]] == 1) ++res; 
 48     }
 49 }
 50 
 51 void change(int ti, int vis, int l, int r)
 52 {
 53     int pos = op[ti].id;
 54     int v = vis ? op[ti].v : op[ti].pre;
 55     if (pos >= l && pos <= r)
 56     {
 57         update(pos, -1);
 58         arr[pos] = v;
 59         update(pos, 1);
 60     }
 61     else arr[pos] = v; 
 62 }
 63 
 64 void Run()
 65 {
 66     while (scanf("%d%d", &n, &q) != EOF)
 67     {
 68         cnt_que = cnt_op = res = 0; 
 69         for (int i = 1; i <= n; ++i) scanf("%d", arr + i); 
 70         for (int i = 1; i <= n; ++i) brr[i] = arr[i];
 71         char opp;
 72         for (int i = 1; i <= q; ++i)
 73         {
 74             scanf(" %c", &opp); 
 75             if (opp == 'Q') que[++cnt_que].scan(cnt_que, cnt_op);
 76             else op[++cnt_op].scan();
 77         }
 78         sort(que + 1, que + 1 + cnt_que);
 79         for (int i = 1, l = 1, r = 0, ti = 0; i <= cnt_que; ++i)
 80         {
 81             for (; ti < que[i].ti; ++ti) change(ti + 1, 1, l, r);
 82             for (; ti > que[i].ti; --ti) change(ti, 0, l, r);
 83             for (; r < que[i].r; ++r) update(r + 1, 1);
 84             for (; r > que[i].r; --r) update(r, -1);
 85             for (; l < que[i].l; ++l) update(l, -1);
 86             for (; l > que[i].l; --l) update(l - 1, 1);
 87             ans[que[i].id] = res;
 88         }
 89         for (int i = 1; i <= cnt_que; ++i) printf("%d\n", ans[i]);
 90     }
 91 }
 92 
 93 int main()
 94 {
 95     #ifdef LOCAL
 96         freopen("Test.in", "r", stdin);
 97     #endif
 98 
 99     Run();
100     return 0;
101 }
View Code

 2141:分块+树状数组

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 20010
 5 #define block 200
 6 
 7 int n, m, q;
 8 int arr[N], brr[N], pos[N], num[N];
 9 
10 struct BIT
11 {
12     int a[N];
13     void update(int x, int val)
14     {
15         while (x <= n)
16         {
17             a[x] += val;
18             x += x & -x;
19         }
20     }
21 
22     int query(int x)
23     {
24         int res = 0;
25         while (x)
26         {
27             res += a[x];
28             x -= x & -x;
29         }
30         return res; 
31     }
32 
33 }bit[block];
34 
35 int query(int x)
36 {
37     int res = 0;
38     for (int i = 1; i < pos[x]; ++i)
39         res += num[i] - bit[i].query(arr[x]); 
40     for (int i = x - 1; i >= 1 && pos[i] == pos[x]; --i) if (arr[i] > arr[x]) 
41         ++res;
42     for (int i = x + 1; i <= n && pos[i] == pos[x]; ++i) if (arr[i] < arr[x])
43         ++res;
44     for (int i = pos[x] + 1; i <= pos[n]; ++i)
45         res += bit[i].query(arr[x] - 1); 
46     return res;
47 }
48 
49 void Run()
50 {
51     while (scanf("%d", &n) != EOF)
52     {
53         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
54         for (int i = 1; i <= n; ++i) brr[i] = arr[i]; 
55         sort(brr + 1, brr + 1 + n);
56         m = unique(brr + 1, brr + 1 + n) - brr - 1;
57         for (int i = 1; i <= n; ++i) arr[i] = lower_bound(brr + 1, brr + 1 + m, arr[i]) - brr;
58         for (int i = 1; i <= n; ++i) pos[i] = (i - 1) / block + 1, ++num[pos[i]];
59         int res = 0;
60         for (int i = 1; i <= n; ++i)
61         {
62             bit[0].update(arr[i], 1);
63             res += i - bit[0].query(arr[i]);
64         }
65         printf("%d\n", res);
66         for (int i = 1; i <= n; ++i) bit[pos[i]].update(arr[i], 1);
67         scanf("%d", &q);
68         for (int i = 1, l, r; i <= q; ++i)
69         {
70             scanf("%d%d", &l, &r);
71             if (l > r) swap(l, r);
72             res -= query(l);
73             res -= query(r);
74             if (arr[l] > arr[r]) ++res;
75             bit[pos[l]].update(arr[l], -1);
76             bit[pos[r]].update(arr[r], -1);
77             swap(arr[l], arr[r]);
78             bit[pos[l]].update(arr[l], 1);
79             bit[pos[r]].update(arr[r], 1);
80             res += query(l); 
81             res += query(r);
82             if (arr[l] > arr[r]) --res;
83             printf("%d\n", res);
84         }
85     }
86 }
87 
88 int main()
89 {
90     #ifdef LOCAL
91         freopen("Test.in", "r", stdin);
92     #endif
93 
94     Run();
95     return 0;
96 }
View Code

2157:树剖+线段树

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3  
  4 #define N 100010
  5 #define INF 0x3f3f3f3f
  6 int n, q;
  7 struct Edge { int u, v, w; Edge() {} Edge(int u, int v, int w) : u(u), v(v), w(w) {}}edge[N];
  8 vector <int> G[N];
  9 int p[N], fp[N], sze[N], son[N], fa[N], deep[N], top[N], cnt;
 10  
 11 void DFS(int u)
 12 {
 13     sze[u] = 1;
 14     for (int i = 0, len = G[u].size(); i < len; ++i)
 15     {
 16         int v = G[u][i];
 17         if (v == fa[u]) continue;
 18         fa[v] = u;
 19         deep[v] = deep[u] + 1;
 20         DFS(v); sze[u] += sze[v];
 21         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
 22     }
 23 }
 24  
 25 void getpos(int u, int sp)
 26 {
 27     top[u] = sp;
 28     p[u] = ++cnt;
 29     fp[cnt] = u;
 30     if (!son[u]) return;
 31     getpos(son[u], sp);
 32     for (int i = 0, len = G[u].size(); i < len; ++i)
 33     {
 34         int v = G[u][i];
 35         if (v == fa[u] || v == son[u]) continue;
 36         getpos(v, v);
 37     }
 38 }
 39  
 40 struct SEG
 41 {
 42     struct node
 43     {
 44         int sum, Max, Min, lazy;
 45         void init() 
 46         {
 47             sum = 0;
 48             Max = -INF;
 49             Min = INF;
 50             lazy = 1;
 51         }
 52         node operator + (const node &r) const
 53         {
 54             node res; res.init(); 
 55             res.sum = sum + r.sum;
 56             res.Max = max(Max, r.Max);
 57             res.Min = min(Min, r.Min);
 58             return res;
 59         }   
 60         void change() 
 61         {
 62             sum *= -1;
 63             Max *= -1;
 64             Min *= -1;
 65             lazy *= -1;
 66             swap(Max, Min);
 67         }
 68     }a[N << 2], res;  
 69     void build(int id, int l, int r)
 70     {
 71         a[id].init();
 72         if (l == r) return;
 73         int mid = (l + r)  >> 1;
 74         build(id << 1, l, mid);
 75         build(id << 1 | 1, mid + 1, r);
 76     }
 77     void pushdown(int id)
 78     {
 79         if (a[id].lazy != 1)
 80         {
 81             a[id].lazy = 1;
 82             a[id << 1].change();
 83             a[id << 1 | 1].change();
 84         }
 85     }
 86     void update(int id, int l, int r, int pos, int val)
 87     {
 88         if (l == r) 
 89         {
 90             a[id].sum = a[id].Max = a[id].Min = val;
 91             return;
 92         }
 93         pushdown(id);
 94         int mid = (l + r) >> 1;
 95         if (pos <= mid) update(id << 1, l, mid, pos, val);
 96         else update(id << 1 | 1, mid + 1, r, pos, val);
 97         a[id] = a[id << 1] + a[id << 1 | 1];
 98     }
 99     void update(int id, int l, int r, int ql, int qr, int val)
100     {
101         if (l >= ql && r <= qr)
102         {
103             a[id].change();
104             return;
105         }
106         pushdown(id);
107         int mid = (l + r) >> 1;
108         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
109         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
110         a[id] = a[id << 1] + a[id << 1 | 1];
111     }
112     void query(int id, int l, int r, int ql, int qr)
113     {
114         if (l >= ql && r <= qr) 
115         {
116             res = res + a[id];
117             return;
118         }
119         pushdown(id);
120         int mid = (l + r) >> 1;
121         if (ql <= mid) query(id << 1, l, mid, ql, qr);
122         if (qr > mid) query(id << 1 | 1, mid + 1, r, ql, qr);
123         a[id] = a[id << 1] + a[id << 1 | 1];
124     }
125 }seg;
126  
127 void update(int u, int v)
128 {
129     while (top[u] != top[v])
130     {
131         if (deep[top[u]] < deep[top[v]])
132             swap(u, v);
133         seg.update(1, 1, n, p[top[u]], p[u], -1);
134         u = fa[top[u]];
135     }
136     if (u == v) return;
137     if (deep[u] > deep[v]) swap(u, v);
138     seg.update(1, 1, n, p[son[u]], p[v], -1); 
139 }
140  
141 void query(int u, int v)
142 {
143     while (top[u] != top[v])
144     {
145         if (deep[top[u]] < deep[top[v]])
146             swap(u, v);
147         seg.query(1, 1, n, p[top[u]], p[u]);
148         u = fa[top[u]];
149     }
150     if (u == v) return;
151     if (deep[u] > deep[v]) swap(u, v);
152     seg.query(1, 1, n, p[son[u]], p[v]);
153 }
154  
155 int main()
156 {
157     while (scanf("%d", &n) != EOF)
158     {
159         cnt = 0;
160         for (int i = 1, u, v, w; i < n; ++i)
161         {
162             scanf("%d%d%d", &u, &v, &w); ++u, ++v;
163             edge[i] = Edge(u, v, w); 
164             G[u].push_back(v);
165             G[v].push_back(u);
166         }
167         DFS(1); 
168         getpos(1, 1); 
169         seg.build(1, 1, n); 
170         for (int i = 1; i < n; ++i)
171         {
172             if (edge[i].u != fa[edge[i].v]) swap(edge[i].u, edge[i].v);
173             seg.update(1, 1, n, p[edge[i].v], edge[i].w);
174         }
175         char op[10]; int u, v;
176         scanf("%d", &q);
177         for (int i = 1; i <= q; ++i)
178         {
179             scanf("%s%d%d", op, &u, &v); ++u, ++v;
180             if (op[0] == 'N') update(u, v);
181             else if (op[0] == 'C') seg.update(1, 1, n, p[edge[u - 1].v], v - 1);
182             else
183             {
184                 seg.res.init();
185                 query(u, v);
186                 if (op[0] == 'S') printf("%d\n", seg.res.sum);
187                 else if (op[1] == 'I') printf("%d\n", seg.res.Min);
188                 else printf("%d\n", seg.res.Max);
189             }
190         }
191     }
192     return 0;
193 }
View Code

2286:虚数+树形DP

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define INFLL 0x3f3f3f3f3f3f3f3f
  5 #define ll long long
  6 #define N 250010
  7 int n, q;
  8   
  9 struct Edge
 10 { 
 11     struct node
 12     {
 13         int to, nx, w;
 14         node() {}
 15         node(int to, int nx, int w) : to(to), nx(nx), w(w) {}
 16     }a[N << 1];
 17     int head[N], pos;
 18     void add(int u, int v, int w) 
 19     {
 20         a[++pos] = node(v, head[u], w); head[u] = pos;
 21         a[++pos] = node(u, head[v], w); head[v] = pos; 
 22     }
 23 }g[2];  
 24 #define erp(id, u) for (int it = g[id].head[u], v = g[id].a[it].to; it; it = g[id].a[it].nx, v = g[id].a[it].to) 
 25 
 26 int p[N], cnt, deep[N], fa[N], sze[N], son[N], top[N], vis[N]; ll val[N];
 27 void DFS(int u)
 28 {
 29     sze[u] = 1; 
 30     erp(0, u) if (v != fa[u])  
 31     {
 32         fa[v] = u;
 33         deep[v] = deep[u] + 1;
 34         val[v] = min(val[u], (ll)g[0].a[it].w);  
 35         DFS(v); sze[u] += sze[v]; 
 36         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;   
 37     }
 38 }
 39 
 40 void getpos(int u, int sp) 
 41 {
 42     top[u] = sp;
 43     p[u] = ++cnt;
 44     if (!son[u]) return;
 45     getpos(son[u], sp);
 46     erp(0, u) if (v != fa[u] && v != son[u])
 47         getpos(v, v); 
 48 }
 49 
 50 int querylca(int u, int v)  
 51 {
 52     while (top[u] != top[v]) 
 53     {
 54         if (deep[top[u]] < deep[top[v]]) swap(u, v);
 55         u = fa[top[u]];
 56     }
 57     if (deep[u] > deep[v]) swap(u, v);
 58     return u;
 59 }
 60 
 61 ll dp(int u, int fa) 
 62 {
 63     ll tmp = 0;         
 64     erp(1, u) if (v != fa) tmp += dp(v, u);  
 65     g[1].head[u] = 0; 
 66     if (tmp == 0 || vis[u]) return vis[u] = 0, val[u]; 
 67     return min(val[u], tmp); 
 68 }
 69 
 70 bool cmp(int a, int b) { return p[a] < p[b]; } 
 71 
 72 int a[N], stk[N], stktop; 
 73 void Run()
 74 {
 75     while (scanf("%d", &n) != EOF)
 76     {
 77         val[1] = INFLL;  
 78         for (int i = 1, u, v, w; i < n; ++i)
 79         {
 80             scanf("%d%d%d", &u, &v, &w);
 81             g[0].add(u, v, w);
 82         }DFS(1); getpos(1, 1);
 83         scanf("%d", &q); 
 84         for (int qq = 1, k; qq <= q; ++qq)
 85         {
 86             scanf("%d", &k); 
 87             for (int i = 1; i <= k; ++i) scanf("%d", a + i), vis[a[i]] = 1; 
 88             sort(a + 1, a + 1 + k, cmp);    
 89             stk[stktop = 1] = 1; g[1].pos = 0;
 90             for (int i = 1; i <= k; ++i) 
 91             {
 92                 int lca = querylca(a[i], stk[stktop]);
 93                 while (deep[lca] < deep[stk[stktop]]) 
 94                 {
 95                     if (deep[stk[stktop - 1]] <= deep[lca])
 96                     { 
 97                         int last = stk[stktop--]; 
 98                         if (stk[stktop] != lca) stk[++stktop] = lca;
 99                         g[1].add(last, lca, 0);  
100                         break;
101                     }
102                     g[1].add(stk[stktop], stk[stktop - 1], 0), --stktop; 
103                 } 
104                 if (stk[stktop] != a[i]) stk[++stktop] = a[i]; 
105             } 
106             while (stktop > 1) g[1].add(stk[stktop], stk[stktop - 1], 0), --stktop;  
107             printf("%lld\n", dp(1, 1));   
108         } 
109     }
110 }
111 
112 int main()
113 {
114     #ifdef LOCAL
115         freopen("Test.in", "r", stdin);
116     #endif 
117 
118     Run();
119     return 0;
120 }
View Code

2654:二分+Kruskal()

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 struct node
 6 {
 7     int u, v, clo, base, w;
 8     void scan() 
 9     { 
10         scanf("%d%d%d%d", &u, &v, &base, &clo);
11            ++u, ++v;
12         if (clo == 1) w = base;   
13     }
14     bool operator < (const node &r) const
15     {
16         return w < r.w || (w == r.w && clo < r.clo); 
17     }
18 }edge[N];
19 int n, m, need;
20 int pre[N];
21 int find(int x) { return pre[x] == 0 ? x : pre[x] = find(pre[x]); }
22 
23 #define pii pair <int, int> 
24 pii Kruskal(int add)
25 {
26     memset(pre, 0, sizeof pre);
27     for (int i = 1; i <= m; ++i) if (edge[i].clo == 0) edge[i].w = add + edge[i].base;
28     sort(edge + 1, edge + 1 + m); 
29     int cnt = 1, cnt_white = 0; 
30     int res = 0;
31     for (int i = 1; i <= m; ++i)
32     {
33         int u = edge[i].u, v = edge[i].v; 
34         int fu = find(u), fv = find(v);
35         if (fu == fv) continue;
36         ++cnt; if (edge[i].clo == 0) ++cnt_white; 
37         res += edge[i].w; 
38         pre[fu] = fv; 
39         if (cnt == n) break; 
40     }
41     return pii(res, cnt_white); 
42 }
43 
44 int main()
45 {
46     while (scanf("%d%d%d", &n, &m, &need) != EOF)
47     {
48         for (int i = 1; i <= m; ++i) edge[i].scan();
49         int l = -100, r = 100, res = 0;
50         while (r - l >= 0)
51         {
52             int mid = (l + r) >> 1;
53             pii tmp = Kruskal(mid); 
54             if (tmp.second >= need) res = tmp.first - mid * need, l = mid + 1;   
55             else r = mid - 1;
56         }
57         printf("%d\n", res);
58     }    
59     return 0;
60 }
View Code

2724:$F[i][j] 表示 第i块到第j块的众数是什么,cntblock[i][j]表示前i块中j这个数出现几次,然后分块维护即可$

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 #define block 650
  6 #define pii pair <int, int>
  7 int n, m, q;
  8 int arr[N], brr[N], cnt[N]; 
  9 int cntblock[block][N], sze; 
 10 pii f[block][block];
 11 
 12 void Hash()
 13 {
 14     for (int i = 1; i <= n; ++i) brr[i] = arr[i];
 15     sort(brr + 1, brr + 1 + n);
 16     m = unique(brr + 1, brr + 1 + n) - brr - 1;
 17     for (int i = 1; i <= n; ++i) arr[i] = lower_bound(brr + 1, brr + 1 + m, arr[i]) - brr;
 18 } 
 19 
 20 void Init() 
 21 {
 22     memset(cntblock, 0, sizeof cntblock); 
 23     memset(f, 0, sizeof f);
 24     memset(cnt, 0, sizeof cnt); 
 25 }
 26 
 27 void clean(int l, int r)
 28 {
 29     for (int i = l; i <= r; ++i)
 30         cnt[arr[i]] = 0;
 31 }
 32 
 33 void Run()
 34 {
 35     while (scanf("%d%d", &n, &q) != EOF)
 36     {
 37         Init(); sze = (n - 1) / block + 1;
 38         for (int i = 1; i <= n; ++i) scanf("%d", arr + i); Hash();
 39         for (int i = 1; i <= n; ++i)
 40         {
 41             int now = (i - 1) / block + 1;
 42             if (i != 1 && (i - 2) / block + 1 != now)
 43                 for (int j = 1; j <= m; ++j)
 44                     cntblock[now][j] = cntblock[now - 1][j];
 45             ++cntblock[now][arr[i]];
 46         }
 47         for (int i = 1; i <= sze; ++i) 
 48         {
 49             for (int j = i; j <= sze; ++j)
 50             {
 51                 f[i][j] = f[i][j - 1];
 52                 int l = (j - 1) * block + 1, r = j * block;
 53                 for (int k = l; k <= r; ++k)
 54                 {
 55                     int num = arr[k];
 56                     if (!cnt[num])
 57                         cnt[num] += cntblock[j - 1][num] - cntblock[i - 1][num];
 58                     ++cnt[num]; 
 59                     if (cnt[num] > f[i][j].first || cnt[num] == f[i][j].first && brr[num] < f[i][j].second)
 60                         f[i][j] = pii(cnt[num], brr[num]); 
 61                 }
 62                 clean(l, r);
 63             }
 64         }
 65         int ans = 0;
 66         for (int i = 1, l, r; i <= q; ++i)
 67         {
 68             scanf("%d%d", &l, &r);
 69             l = (l + ans - 1) % n + 1; 
 70             r = (r + ans - 1) % n + 1;
 71             if (l > r) swap(l, r); 
 72             int posl = (l - 1) / block + 1, posr = (r - 1) / block + 1;
 73             pii res = pii(0, 0);  
 74             if (posl == posr)
 75             {
 76                 for (int j = l; j <= r; ++j)
 77                 {
 78                     int num = arr[j];
 79                     ++cnt[num];
 80                     if (cnt[num] > res.first || cnt[num] == res.first && brr[num] < res.second)
 81                         res = pii(cnt[num], brr[num]); 
 82                 }
 83                 clean(l, r);
 84             }
 85             else
 86             {
 87                 res = f[posl + 1][posr - 1];   
 88                 for (int j = l; j <= posl * block; ++j)
 89                 {
 90                     int num = arr[j];
 91                     if (!cnt[num]) cnt[num] += cntblock[posr - 1][num] - cntblock[posl][num];
 92                     ++cnt[num];
 93                     if (cnt[num] > res.first || cnt[num] == res.first && brr[num] < res.second)
 94                         res = pii(cnt[num], brr[num]);
 95                 }
 96                 for (int j = (posr - 1) * block + 1; j <= r; ++j)
 97                 {
 98                     int num = arr[j];
 99                     if (!cnt[num]) cnt[num] += cntblock[posr - 1][num] - cntblock[posl][num];
100                     ++cnt[num];
101                     if (cnt[num] > res.first || cnt[num] == res.first && brr[num] < res.second)
102                         res = pii(cnt[num], brr[num]);
103                 }
104                 clean(l, posl * block);
105                 clean((posr - 1) * block + 1, r);
106             }
107             printf("%d\n", res.second);
108             ans = res.second; 
109         }
110     }
111 }
112 
113 int main()
114 {
115     #ifdef LOCAL
116         freopen("Test.in", "r", stdin);
117     #endif 
118 
119     Run();
120     return 0;
121 }
View Code

2729:先排男生和老师,老师相邻和不相邻,相邻的话需要插入一个女生

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 import java.io.BufferedInputStream;
 2 import java.util.Scanner;
 3 import java.math.*;
 4 
 5 public class Main {
 6 
 7     static BigInteger fac[] = new BigInteger[4100];
 8     public static void init()
 9     {
10         fac[0] = BigInteger.ONE;
11         for (int i = 1; i < 4100; ++i)
12             fac[i] = fac[i - 1].multiply(BigInteger.valueOf(i));
13     }
14 
15     public static BigInteger C(int n, int m)
16     {
17         if (n < m || n < 0 || m < 0) return BigInteger.ZERO;
18         return fac[n].divide(fac[m]).divide(fac[n - m]);
19     }
20 
21     public static void main(String[] args)
22     {
23         init();
24         Scanner in = new Scanner(new BufferedInputStream(System.in));
25         int n, m;
26         while (in.hasNext())
27         {
28             n = in.nextInt();
29             m = in.nextInt();
30             BigInteger a, b;
31             a = BigInteger.valueOf(2).multiply(fac[n + 1]).multiply(fac[m]).multiply(C(n + 2, m - 1));
32             b = BigInteger.valueOf(2).multiply(fac[n]).multiply(fac[m]).multiply(C(n + 1, 2)).multiply(C(n + 3, m));
33             System.out.println(a.add(b));
34         }
35         in.close();
36     }
37 }
View Code

2738:整体二分

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 510
  5 #define M 60010
  6 #define INF 0x3f3f3f3f
  7 int n, q, m;
  8 struct node
  9 {
 10     int x, y, v;
 11     void scan(int x, int y)
 12     {
 13         this->x = x; this->y = y;
 14         scanf("%d", &v);
 15     }
 16     bool operator < (const node &r) const { return v < r.v; }
 17 }arr[N * N];
 18 
 19 struct BIT
 20 {
 21     int a[N][N];
 22     void Init() { memset(a, 0, sizeof a); }
 23     void update(int x, int y, int val) 
 24     {
 25         for (int i = x; i <= n; i += i & -i)
 26             for (int j = y; j <= n; j += j & -j)
 27                 a[i][j] += val;
 28     }
 29     int query(int x, int y)
 30     {
 31         int res = 0;
 32         for (int i = x; i; i -= i & -i)
 33             for (int j = y; j; j -= j & -j)
 34                 res += a[i][j];
 35         return res;
 36     }
 37     int query(int x[], int y[])
 38     {
 39         int res = 0;
 40         res += query(x[0] - 1, y[0] - 1);
 41         res += query(x[1], y[1]);
 42         res -= query(x[0] - 1, y[1]);
 43         res -= query(x[1], y[0] - 1);
 44         return res; 
 45     }
 46 }bit;
 47 
 48 struct qnode
 49 {
 50     int x[2], y[2], k, id;
 51     void scan(int id)
 52     {
 53         this->id = id;
 54         for (int i = 0; i < 2; ++i)
 55             scanf("%d%d", x + i, y + i);
 56         scanf("%d", &k);
 57     } 
 58 }que[M], ql[M], qr[M]; int ans[M];
 59 
 60 void CDQ(int L, int R, int l, int r)
 61 {
 62     if (L > R) return;
 63     if (l == r)
 64     {
 65         for (int i = L; i <= R; ++i)
 66             ans[que[i].id] = arr[l].v; 
 67         return;  
 68     }
 69     int mid = (l + r) >> 1;
 70     for (int i = l; i <= mid; ++i) bit.update(arr[i].x, arr[i].y, 1);
 71     int posl = 0, posr = 0;  
 72     for (int i = L; i <= R; ++i)
 73     {
 74         int sze = bit.query(que[i].x, que[i].y);
 75         if (sze < que[i].k)  
 76         {
 77             que[i].k -= sze;
 78             qr[++posr] = que[i];    
 79         }
 80         else
 81             ql[++posl] = que[i];
 82     }
 83     for (int i = 1; i <= posl; ++i) que[L + i - 1] = ql[i];
 84     for (int i = 1; i <= posr; ++i) que[L + posl + i - 1] = qr[i];
 85     for (int i = l; i <= mid; ++i) bit.update(arr[i].x, arr[i].y, -1);
 86     CDQ(L, L + posl - 1, l, mid);
 87     CDQ(L + posl, R, mid + 1, r);
 88 }
 89 
 90 int main()
 91 {
 92     while (scanf("%d%d", &n, &q) != EOF)
 93     {
 94         m = 0; bit.Init();
 95         for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) arr[++m].scan(i, j);
 96         sort(arr + 1, arr + 1 + m);
 97         for (int i = 1; i <= q; ++i) que[i].scan(i);
 98         CDQ(1, q, 1, m); 
 99         for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
100     }
101     return 0;
102 }
View Code

2750:$f[u] 表示st -> u的路径数,g[v] 表示 v所能到达的点数  那么一条边<u, v> 提供的贡献就是 f[u] \cdot g[v]$

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define N 5010
  6 #define INF 0x3f3f3f3f
  7 const ll MOD = (ll)1e9 + 7;
  8 int n, m; ll ans[N];
  9 
 10 struct Graph
 11 {
 12     struct node
 13     {
 14         int to, nx, w, id;
 15         node() {}
 16         node(int to, int nx, int w, int id) : to(to), nx(nx), w(w), id(id) {}
 17     }a[N << 1]; int head[N], pos;
 18     void init()
 19     {
 20         memset(head, -1, sizeof head);
 21         pos = 0;
 22     }
 23     void add(int u, int v, int w, int id)
 24     {
 25         a[++pos] = node(v, head[u], w, id); head[u] = pos;
 26     }
 27 }G[2];
 28 #define erp(G, u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w, id = G.a[it].id; ~it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w, id = G.a[it].id)
 29 
 30 namespace Dijkstra
 31 {
 32     struct node
 33     {
 34         int to, w;
 35         node() {}
 36         node(int to, int w) : to(to), w(w) {}
 37         bool operator < (const node &r) const { return w > r.w; }
 38     };
 39     int dist[N]; bool used[N];
 40     void work(int st)
 41     {
 42         for (int i = 1; i <= n; ++i) dist[i] = INF, used[i] = false;
 43         priority_queue <node> q; q.push(node(st, 0)); dist[st] = 0;
 44         while (!q.empty())
 45         {
 46             int u = q.top().to; q.pop();
 47             erp(G[0], u) if (!used[v] && dist[v] > dist[u] + w)
 48             {
 49                 dist[v] = dist[u] + w;
 50                 q.push(node(v, w)); 
 51             } 
 52         }
 53     }
 54 }
 55 
 56 int f[N], g[N], in[N];
 57 void Topo(int p, int *x)
 58 {
 59     G[1].init(); 
 60     for (int i = 1; i <= n; ++i) x[i] = p, in[i] = 0;
 61     for (int u = 1; u <= n; ++u) if (Dijkstra::dist[u] != INF)
 62     {
 63         erp(G[0], u) if (Dijkstra::dist[u] + w <= Dijkstra::dist[v])
 64         {
 65             if (!p)
 66             {
 67                 G[1].add(u, v, w, id);
 68                 ++in[v];
 69             }
 70             else
 71             {
 72                 G[1].add(v, u, w, id);
 73                 ++in[u];
 74             }
 75         }
 76     }
 77     
 78     queue <int> q;
 79     for (int u = 1; u <= n; ++u) if (Dijkstra::dist[u] != INF && !in[u])
 80     {
 81         x[u] = 1;
 82         q.push(u);
 83     }
 84 
 85     while (!q.empty())
 86     {
 87         int u = q.front(); q.pop();
 88         erp(G[1], u) 
 89         {
 90             x[v] += x[u]; 
 91             --in[v];
 92             if (!in[v]) q.push(v);
 93         }
 94     }    
 95 }
 96 
 97 void Run()
 98 {
 99     while (scanf("%d%d", &n, &m) != EOF)
100     {
101         G[0].init();
102         memset(ans, 0, sizeof ans);
103         for (int i = 1, u, v, w; i <= m; ++i)
104         {
105             scanf("%d%d%d", &u, &v, &w);
106             G[0].add(u, v, w, i);
107         }
108         for (int i = 1; i <= n; ++i)
109         {
110             Dijkstra::work(i);
111             Topo(1, g);
112             Topo(0, f);
113             for (int u = 1; u <= n; ++u) erp(G[1], u)
114                 ans[id] = (ans[id] + 1ll * f[u] * g[v]) % MOD;
115         }
116         for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
117     }
118 }
119 
120 int main()
121 {
122     #ifdef LOCAL
123         freopen("Test.in", "r", stdin);
124     #endif 
125 
126     Run();
127     return 0; 
128 }
View Code

2752:线段树维护,注意区间的合并

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 #define ll long long 
  6 int n, q;
  7 
  8 ll calc(ll x) { return x * (x + 1) / 2; } 
  9 ll base[N]; 
 10 struct SEG
 11 {
 12     struct node
 13     {
 14         ll sum, res, lsum, rsum, lazy, cnt, sze;
 15         node() {}
 16         node(ll sum, ll res, ll lsum, ll rsum, ll lazy, ll cnt, ll sze) : sum(sum), res(res), lsum(lsum), rsum(rsum), lazy(lazy), cnt(cnt), sze(sze) {}
 17         node operator + (const node &r) const
 18         {
 19             node ans = node(0, 0, 0, 0, 0, 0, 0); 
 20             ans.sum = sum + r.sum;
 21             ans.res = res + r.res + rsum * r.cnt + r.lsum * cnt;
 22             ans.lsum = lsum + r.lsum + sum * r.cnt;
 23             ans.rsum = rsum + r.rsum + r.sum * cnt;
 24             ans.cnt = cnt + r.cnt; 
 25             ans.sze = sze + r.sze + cnt * r.cnt;  
 26             return ans;
 27         }
 28     }a[N << 2], res;
 29     void change(int id, ll val)
 30     {
 31         a[id].sum += a[id].cnt * val;
 32         a[id].res += base[a[id].cnt] * val;  
 33         a[id].lsum += calc(a[id].cnt) * val;
 34         a[id].rsum += calc(a[id].cnt) * val;
 35         a[id].lazy += val; 
 36     }
 37     void pushdown(int id)
 38     {
 39         if (!a[id].lazy) return;
 40         change(id << 1, a[id].lazy);
 41         change(id << 1 | 1, a[id].lazy);
 42         a[id].lazy = 0; 
 43     }
 44     void build(int id, int l, int r)
 45     {
 46         if (l == r)
 47         {
 48             a[id] = node(0, 0, 0, 0, 0, 1, 1);
 49             return;
 50         }
 51         int mid = (l + r) >> 1;
 52         build(id << 1, l, mid);
 53         build(id << 1 | 1, mid + 1, r);
 54         a[id] = a[id << 1] + a[id << 1 | 1]; 
 55     }
 56     void update(int id, int l, int r, int ql, int qr, ll val) 
 57     {
 58         if (l >= ql && r <= qr)
 59         {
 60             change(id, val);
 61             return; 
 62         }
 63         pushdown(id);
 64         int mid = (l + r) >> 1;
 65         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
 66         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
 67         a[id] = a[id << 1] + a[id << 1 | 1];
 68         return;
 69     }
 70     node query(int id, int l, int r, int ql, int qr)
 71     {
 72         if (l >= ql && r <= qr) return a[id];
 73         pushdown(id);
 74         int mid = (l + r) >> 1;
 75         node res = node(0, 0, 0, 0, 0, 0, 0); 
 76         if (ql <= mid) res = query(id << 1, l, mid, ql, qr);
 77         if (qr > mid) res = res.cnt ? res + query(id << 1 | 1, mid + 1, r, ql, qr) : query(id << 1 | 1, mid + 1, r, ql, qr);
 78         a[id] = a[id << 1] + a[id << 1 | 1];
 79         return res;
 80     }
 81 }seg;
 82 
 83 ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
 84 
 85 void Run()
 86 {
 87     for (int i = 1; i <= 100000; ++i) base[i] = base[i - 1] + calc(i);
 88     while (scanf("%d%d", &n, &q) != EOF)
 89     {
 90         seg.build(1, 1, n);
 91         char op; int l, r, v; 
 92         for (int i = 1; i <= q; ++i)
 93         {
 94             scanf(" %c%d%d", &op, &l, &r); ++l;
 95             if (op == 'C')
 96             {
 97                 scanf("%d", &v);
 98                 seg.update(1, 1, n, l, r, v);
 99             }
100             else
101             {
102                 seg.res = seg.query(1, 1, n, l, r); 
103                 ll a = seg.res.res, b = seg.res.sze;
104                 ll t = gcd(a, b);
105                 a /= t, b /= t;
106                 printf("%lld/%lld\n", a, b);
107             }
108         }
109     }
110 }
111 
112 int main()
113 {
114     #ifdef LOCAL
115         freopen("Test.in", "r", stdin);
116     #endif 
117 
118     Run();
119     return 0;
120 }
View Code

3100:单调队列维护左端点,枚举右端点

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1000001
 5 int n, res;
 6 int arr[N], pre[N], q[N]; 
 7 
 8 void check(int l, int r, int pos)
 9 {
10     if (pos > r) return;
11     if (r - l + 1 == arr[pos]) res = max(res, r - l + 1);
12 }
13 
14 void Run()
15 {
16     while (scanf("%d", &n) != EOF)
17     {
18         res = 0; 
19         int l = 1, r = 0, L = 1;
20         for (int i = 1; i <= n; ++i)
21         {
22             scanf("%d", arr + i);
23             L = max(L, pre[arr[i]] + 1);
24             while (l <= r && q[l] <= pre[arr[i]])
25             {
26                 check(q[l] + 1, i - 1, q[l + 1]);
27                 ++l;
28             }
29             pre[arr[i]] = i;
30             while (l <= r && arr[i] >= arr[q[r]])
31             {
32                 check(max(L, q[r - 1] + 1), i - 1, q[r]);  
33                 --r; 
34             }
35             q[++r] = i;
36             check(L, i, q[l]);
37         }
38         printf("%d\n", res);
39     }
40 }
41 
42 int main()
43 {
44     #ifdef LOCAL
45         freopen("Test.in", "r", stdin);
46     #endif 
47 
48     Run();
49     return 0;
50 
51 }
View Code

3110:整体二分+线段树

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 50010
  5 #define ll long long
  6 
  7 int n, q, m;
  8 ll ans[N];
  9 
 10 struct SEG
 11 {
 12     struct node
 13     {
 14         ll cnt, lazy, sum;
 15         node() {}
 16         node(int l, int r)
 17         {
 18             cnt = r - l + 1;
 19             lazy = sum = 0;
 20         }
 21     }a[N << 2];
 22 
 23     void pushup(int id)
 24     {
 25         a[id].sum = a[id << 1].sum + a[id << 1 | 1].sum;
 26     }
 27     
 28     void pushdown(int id)
 29     {
 30         if (a[id].lazy)
 31         {
 32             int lazy = a[id].lazy; a[id].lazy = 0;
 33             a[id << 1].lazy += lazy;
 34             a[id << 1 | 1].lazy += lazy;
 35             a[id << 1].sum += lazy * a[id << 1].cnt;
 36             a[id << 1 | 1].sum += lazy * a[id << 1 | 1].cnt;
 37         }
 38     }
 39 
 40     void build(int id, int l, int r)
 41     {
 42         a[id] = node(l, r);
 43         if (l == r) return;
 44         int mid = (l + r) >> 1;
 45         build(id << 1, l, mid);
 46         build(id << 1 | 1, mid + 1, r);
 47     }
 48 
 49 
 50     void update(int id, int l, int r, int ql, int qr, ll val)
 51     {
 52         if (l >= ql && r <= qr)
 53         {
 54             a[id].lazy += val;
 55             a[id].sum += val * a[id].cnt;
 56             return;
 57         }
 58         pushdown(id);
 59         int mid = (l + r) >> 1;
 60         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
 61         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
 62         pushup(id);
 63     }
 64 
 65     ll query(int id, int l, int r, int ql, int qr)
 66     {
 67         if (l >= ql && r <= qr) return a[id].sum;
 68         pushdown(id);
 69         int mid = (l + r) >> 1;
 70         ll res = 0;
 71         if (ql <= mid) res += query(id << 1, l, mid, ql, qr);
 72         if (qr > mid) res += query(id << 1 | 1, mid + 1, r, ql, qr);
 73         pushup(id);
 74         return res;
 75     }
 76 }segtree;
 77 
 78 struct QUE
 79 {
 80     int op, x, y, id; ll c;
 81     void scan()
 82     {
 83         scanf("%d%d%d%lld", &op, &x, &y, &c);
 84         if (op == 2) id = ++m;
 85     }
 86 }que[N], quel[N], quer[N];
 87 
 88 
 89 void solve(int ql, int qr, int l, int r)
 90 {
 91     if (ql > qr) return; 
 92     if (l == r)
 93     {
 94         for (int i = ql; i <= qr; ++i) if (que[i].op == 2) 
 95             ans[que[i].id] = l;
 96         return;
 97     }
 98     int mid = (l + r) >> 1, cnt_ql = 0, cnt_qr = 0;
 99     for (int i = ql; i <= qr; ++i)
100     {
101         if (que[i].op == 1)
102         {
103             if (que[i].c > mid) segtree.update(1, 1, n, que[i].x, que[i].y, 1), quer[++cnt_qr] = que[i];
104             else quel[++cnt_ql] = que[i];
105         }
106         else
107         {
108             ll tmp = segtree.query(1, 1, n, que[i].x, que[i].y);
109             if (tmp < que[i].c) que[i].c -= tmp, quel[++cnt_ql] = que[i];
110             else quer[++cnt_qr] = que[i];
111         }
112     }
113     for (int i = 1; i <= cnt_qr; ++i) if (quer[i].op == 1) segtree.update(1, 1, n, quer[i].x, quer[i].y, -1); 
114     for (int i = 1; i <= cnt_ql; ++i) que[ql + i - 1] = quel[i];
115     for (int i = 1; i <= cnt_qr; ++i) que[ql + cnt_ql + i - 1] = quer[i];
116     solve(ql, ql + cnt_ql - 1, l, mid);
117     solve(ql + cnt_ql, qr, mid + 1, r);
118 }
119 
120 void Run()
121 {
122     while (scanf("%d%d", &n, &q) != EOF)
123     {
124         for (int i = 1; i <= q; ++i) que[i].scan(); 
125         segtree.build(1, 1, n);
126         solve(1, q, -N, N);
127         for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);
128     }
129 }
130 
131 int main()
132 {
133     #ifdef LOCAL
134         freopen("Test.in", "r", stdin); 
135     #endif
136 
137     Run();
138     return 0;
139 }
View Code

3155:硬核线段树

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 100010
 6 int n, m;
 7 ll arr[N];
 8 
 9 struct SEG
10 {
11     ll sum[N << 2][2];
12     int cnt[N << 2];
13     void pushup(int id)
14     {
15         sum[id][0] = sum[id << 1][0] + sum[id << 1 | 1][0];
16         sum[id][1] = sum[id << 1][1] + sum[id << 1 | 1][1] + cnt[id << 1 | 1] * sum[id << 1][0];
17     }
18     void build(int id, int l, int r)
19     {
20         cnt[id] = r - l + 1;
21         if (l == r)
22         {
23             sum[id][0] = sum[id][1] = arr[l];
24             return;
25         }
26         int mid = (l + r) >> 1;
27         build(id << 1, l, mid);
28         build(id << 1 | 1, mid + 1, r);
29         pushup(id);
30     }
31     void update(int id, int l, int r, int pos, ll val) 
32     {
33         if (l == r)
34         {
35             sum[id][0] = sum[id][1] = val;
36             return;
37         }
38         int mid = (l + r) >> 1;
39         if (pos <= mid) update(id << 1, l, mid, pos, val);
40         else update(id << 1 | 1, mid + 1, r, pos, val);
41         pushup(id);
42     }
43     ll query(int id, int l, int r, int ql, int qr)
44     {
45         if (l >= ql && r <= qr) return sum[id][0] * (qr - r) + sum[id][1];
46         int mid = (l + r) >> 1;
47         ll res = 0;
48         if (ql <= mid) res += query(id << 1, l, mid, ql, qr);
49         if (qr > mid) res += query(id << 1 | 1, mid + 1, r, ql, qr);
50         return res;
51     }
52 }seg;
53 
54 void Run() 
55 {
56     while (scanf("%d%d", &n, &m) != EOF)
57     {
58         for (int i = 1; i <= n; ++i) scanf("%lld", arr + i);
59         seg.build(1, 1, n);
60         char op[10]; int x, y;
61         for (int i = 1; i <= m; ++i)
62         {
63             scanf("%s%d", op, &x);
64             if (op[0] == 'Q') printf("%lld\n", seg.query(1, 1, n, 1, x));
65             else
66             {
67                 scanf("%d", &y);
68                 seg.update(1, 1, n, x, y);
69             }
70         }
71     }
72 }
73 
74 int main()
75 {
76     #ifdef LOCAL
77         freopen("Test.in", "r", stdin);
78     #endif 
79 
80     Run();
81     return 0;
82 
83 }
View Code

3173:离线+BIT+二分

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int n;
 6 int a[N], b[N], ans[N];
 7 
 8 struct BIT_Max
 9 {
10     int a[N];
11     void init() { memset(a, 0, sizeof a); }
12     void update(int x, int val) { for (; x <= n; x += x & -x) a[x] = max(a[x], val); }
13     int query(int x) { int res = 0; for (; x; x -= x & -x) res = max(res, a[x]); return res; }  
14 }bit_max;
15 
16 struct BIT_sum
17 {
18     int a[N];
19     void init() { memset(a, 0, sizeof a); }
20     void update(int x, int val) { for (; x <= n; x += x & -x) a[x] += val; }
21     int query(int x) { int res = 0; for (; x; x -= x & -x) res += a[x]; return res; }
22 }bit_sum;
23 
24 void Run() 
25 {
26     while (scanf("%d", &n) != EOF)
27     {
28         for (int i = 1; i <= n; ++i) scanf("%d", a + i), ++a[i]; 
29         bit_sum.init(); 
30         for (int i = 1; i <= n; ++i) bit_sum.update(i, 1);  
31         for (int i = n; i >= 1; --i) 
32         { 
33             int l = 1, r = n, pos; 
34             while (r - l >= 0)
35             {
36                 int mid = (l + r) >> 1; 
37                 int num = bit_sum.query(mid);
38                 if (num == a[i])
39                     pos = mid;
40                 if (num >= a[i]) r = mid - 1; 
41                 else l = mid + 1; 
42             }
43             b[i] = pos;   
44             bit_sum.update(pos, -1); 
45         }
46         bit_max.init();  
47         for (int i = 1; i <= n; ++i)
48         {
49             int res = bit_max.query(b[i]) + 1; 
50             bit_max.update(b[i], res);
51             ans[i] = bit_max.query(n);  
52         }  
53         for (int i = 1; i <= n; ++i) printf("%d\n", ans[i]);
54     }
55 }
56 
57 int main()
58 {
59     #ifdef LOCAL
60         freopen("Test.in", "r", stdin);
61     #endif 
62 
63     Run();
64     return 0;
65 
66 }
View Code

3262:CDQ分治解决一维,考虑有重复的,将id加入形成四关键字排序使得排序顺序固定,然后前后各扫一遍更新最大答案

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 200010
 5 
 6 int n, k;
 7 int ans[N], cnt[N];
 8 
 9 struct node
10 {
11     int x, y, z, id; 
12     bool isleft;
13     void scan(int id)
14     {
15         this->id = id;
16         scanf("%d%d%d", &x, &y, &z);
17     }
18     bool operator < (const node &r) const
19     {
20         return x == r.x ? (y == r.y ? (z == r.z ? id < r.id : z < r.z) : y < r.y) : x < r.x;
21     }
22     bool operator == (const node &r) const { return x == r.x && y == r.y && z == r.z; }
23 }arr[N], tarr[N];
24 
25 struct BIT
26 {
27     int a[N];
28 
29     void update(int x, int val)
30     {
31         while (x <= k)
32         {
33             a[x] += val;
34             x += x & -x;
35         }
36     }
37 
38     int query(int x)
39     {
40         int res = 0;
41         while (x)
42         {
43             res += a[x];
44             x -= x & -x;
45         }
46         return res;
47     }
48 }bit;
49 
50 bool cmp(node a, node b)
51 {
52     return a.y == b.y ? (a.z == b.z ? (a.x == b.x ? a.id < b.id : a.x < b.x) : a.z < b.z) : a.y < b.y;  
53 } 
54 
55 void CDQ(int l, int r)
56 {
57     if (l == r) return; 
58     int mid = (l + r) >> 1;
59     CDQ(l, mid); CDQ(mid + 1, r);
60     for (int i = l; i <= r; ++i)
61     {
62         tarr[i] = arr[i];
63         if (i <= mid) tarr[i].isleft = true;  
64         else tarr[i].isleft = false;   
65     }
66     sort(tarr + l, tarr + r + 1, cmp);
67     for (int i = l; i <= r; ++i)
68     {
69         if (tarr[i].isleft) bit.update(tarr[i].z, 1);  
70         else ans[tarr[i].id] += bit.query(tarr[i].z);   
71     }  
72     for (int i = l; i <= r; ++i) if (tarr[i].isleft) bit.update(tarr[i].z, -1);    
73 }
74 
75 void Run()
76 {
77     while (scanf("%d%d", &n, &k) != EOF)
78     {
79         for (int i = 1; i <= n; ++i) arr[i].scan(i), ans[i] = 0;  
80         sort(arr + 1, arr + 1 + n);
81         CDQ(1, n);
82         for (int i = n - 1; i >= 1; --i) if (arr[i] == arr[i + 1])
83             ans[arr[i].id] = max(ans[arr[i].id], ans[arr[i + 1].id]);
84         for (int i = 2; i <= n; ++i) if (arr[i] == arr[i - 1])
85             ans[arr[i].id] = max(ans[arr[i].id], ans[arr[i - 1].id]);
86         for (int i = 1; i <= n; ++i) ++cnt[ans[i]];  
87         for (int i = 0; i < n; ++i) printf("%d\n", cnt[i]);
88     }
89 }
90 
91 int main()
92 {
93     #ifdef LOCAL
94         freopen("Test.in", "r", stdin); 
95     #endif 
96 
97     Run();
98     return 0;
99 }
View Code

3295:考虑(t, p, x) 三维偏序问题,分别表示删除的时间,删除的位置,删除的值  用CDQ分治干掉t, 排序干掉p,树状数组干掉x

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 #define ll long long
  6 
  7 int n, m, ttm;
  8 int arr[N], pos[N];
  9 ll ans[N];
 10 bool flag[N];
 11 
 12 struct QUE
 13 {
 14     int t, p, x;
 15     QUE() {}
 16     QUE(int t, int p, int x) : t(t), p(p), x(x) {}
 17     bool operator < (const QUE &r) const
 18     {
 19         return p < r.p;
 20     }
 21 }q[N], tq[N];
 22 
 23 struct BIT
 24 {
 25     int a[N];
 26 
 27     void Init()
 28     {
 29         memset(a, 0, sizeof a);
 30     }
 31 
 32     void update(int x, int val)
 33     {
 34         while (x <= n)
 35         {
 36             a[x] += val;
 37             x += x & -x;
 38         }
 39     }
 40 
 41     int query(int x)
 42     {
 43         int res = 0;
 44         while (x)
 45         {
 46             res += a[x];
 47             x -= x & -x;
 48         }
 49         return res;
 50     }
 51 }bit;
 52 
 53 void CDQ(int l, int r)
 54 {
 55     if (l == r) return;
 56     int mid = (l + r) >> 1;
 57     CDQ(l, mid); CDQ(mid + 1, r); 
 58     for (int i = l; i <= r; ++i)
 59     {
 60         tq[i] = q[i];
 61         if (i > mid) tq[i].t = 0;
 62     }
 63     sort(tq + l, tq + r + 1);
 64     for (int i = l; i <= r; ++i)
 65     {
 66         if (!tq[i].t) bit.update(tq[i].x, 1);
 67         else ans[tq[i].t] += bit.query(n) - bit.query(tq[i].x);
 68     }
 69     for (int i = l; i <= r; ++i) if (!tq[i].t) bit.update(tq[i].x, -1);
 70     for (int i = r; i >= l; --i)
 71     {
 72         if (!tq[i].t) bit.update(tq[i].x, 1);
 73         else ans[tq[i].t] += bit.query(tq[i].x);
 74     }
 75     for (int i = l; i <= r; ++i) if (!tq[i].t) bit.update(tq[i].x, -1);
 76 }
 77 
 78 void Run()
 79 {
 80     while (scanf("%d%d", &n, &m) != EOF)
 81     {
 82         ttm = m; bit.Init(); 
 83         memset(ans, 0, sizeof ans);
 84         memset(flag, 0, sizeof flag);
 85         for (int i = 1; i <= n; ++i)
 86         {
 87             scanf("%d", arr + i);
 88             pos[arr[i]] = i;
 89         }
 90         for (int i = 1, x; i <= m; ++i)
 91         {
 92             scanf("%d", &x);
 93             flag[x] = 1;
 94             q[i] = QUE(i, pos[x], x);
 95         }
 96         for (int i = 1; i <= n; ++i) if (!flag[i])
 97             q[++ttm] = QUE(ttm, pos[i], i); 
 98         CDQ(1, n);
 99         for (int i = n - 1; i >= 1; --i) ans[i] += ans[i + 1];
100         for (int i = 1; i <= m; ++i) printf("%lld\n", ans[i]); 
101     }
102 }
103 
104 int main()
105 {
106     #ifdef LOCAL
107         freopen("Test.in", "r", stdin); 
108     #endif 
109 
110     Run();
111     return 0;
112 }
View Code

3319:考虑一个黑点产生的影响,即只对它的子树产生影响,再用并查集缩点,这样一个点只会处理一次,加了IO优化才过的,应该不是正解。

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3  
  4 #define N 1000010
  5 int n, q;
  6 int lp[N], rp[N], pos[N], deep[N], fa[N], cnt;
  7 struct Edge { int to, nx; }edge[N << 1]; 
  8 int head[N], cntedge;
  9 void add(int u, int v) { edge[++cntedge] = Edge{ v, head[u] }; head[u] = cntedge; }
 10  
 11 void DFS(int u)
 12 {
 13     lp[u] = ++cnt;
 14     for (int it = head[u]; it; it = edge[it].nx)
 15     {
 16         int v = edge[it].to;
 17         if (v == fa[u]) continue; 
 18         pos[v] = it >> 1;
 19         deep[v] = deep[u] + 1;
 20         fa[v] = u;
 21         DFS(v);
 22     }
 23     rp[u] = cnt;
 24 }
 25  
 26 struct SEG
 27 {
 28     int Max[N << 2];
 29     int max(int x, int y)
 30     {
 31         if (deep[x] < deep[y]) return y;
 32         return x;
 33     }
 34     void update(int id, int l, int r, int ql, int qr, int val)
 35     {
 36         if (l >= ql && r <= qr)
 37         {
 38             Max[id] = max(Max[id], val);
 39             return;
 40         }
 41         int mid = (l + r) >> 1;
 42         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
 43         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
 44     } 
 45     int query(int id, int l, int r, int pos)
 46     { 
 47         if (l == r) return Max[id];
 48         int mid = (l + r) >> 1;
 49         if (pos <= mid) return max(Max[id], query(id << 1, l, mid, pos));
 50         else return max(Max[id], query(id << 1 | 1, mid + 1, r, pos));
 51     }
 52 }seg;
 53  
 54 int pre[N];
 55 int find(int x) { return pre[x] == 0 ? x : pre[x] = find(pre[x]); } 
 56  
 57 void modify(int u, int v)
 58 {
 59     u = find(u), v = find(v);
 60     while (u != v) 
 61     {
 62         if (deep[find(fa[u])] < deep[find(fa[v])])  
 63             swap(u, v);
 64         seg.update(1, 1, n, lp[u], rp[u], u);
 65         pre[u] = fa[u]; u = find(u); 
 66     }
 67 }
 68  
 69 namespace FastIO
 70 {
 71     #define BUF_SIZE 10000005
 72     bool IOerror = false;
 73     inline char NC()
 74     {
 75         static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
 76         if (p1 == pend)
 77         {
 78             p1 = buf;
 79             pend = buf + fread(buf, 1, BUF_SIZE, stdin);
 80             if (pend == p1)
 81             {
 82                 IOerror = true;
 83                 return -1;
 84             }
 85         }
 86         return *p1++;
 87     }
 88     inline bool blank(char ch)
 89     {
 90         return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
 91     }
 92     template <typename T>
 93     inline void read(T &x)
 94     {
 95         char ch;
 96         while (blank(ch = NC()));
 97         if (IOerror)
 98         {
 99             x = -1;
100             return;
101         }
102         bool flag = false;
103         if (ch == '-')
104         {
105             flag = true;
106             ch = NC();
107         }
108         if (!isdigit(ch)) while (!isdigit(ch = NC()));
109         for (x = ch - '0'; isdigit(ch = NC()); x = x * 10 + ch - '0');
110         if (flag) x *= -1;
111     }
112     inline void out(int x)
113     {
114         if (x / 10) out(x / 10);
115         putchar(x % 10 + '0');
116     }
117     inline void output(int x) { out(x), putchar('\n'); }
118     #undef BUF_SIZE
119 }using namespace FastIO;
120  
121 void Run()
122 {
123     while (read(n), n != EOF)
124     {
125         read(q);
126         deep[1] = 1; cntedge = 1;
127         for (int i = 1, u, v; i < n; ++i)
128         {
129             read(u), read(v);
130             add(u, v); add(v, u);
131         }
132         DFS(1); 
133         for (int i = 1, op, u, v; i <= q; ++i)
134         {
135             read(op), read(v);
136             if (op == 1) output(pos[seg.query(1, 1, n, lp[v])]);
137             else
138             {
139                 read(u);
140                 modify(u, v);
141             }
142         }
143     }
144 }
145  
146 int main()
147 {
148     #ifdef LOCAL
149         freopen("Test.in", "r", stdin);
150     #endif 
151  
152     Run();
153     return 0;
154 }
View Code

3524:主席树

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 500010
  5 int n, q, m;
  6 int arr[N], brr[N];
  7 
  8 void Hash()
  9 {
 10     for (int i = 1; i <= n; ++i) brr[i] = arr[i];
 11     sort(brr + 1, brr + 1 + n);
 12     m = unique(brr + 1, brr + 1 + n) - brr - 1;
 13     for (int i = 1; i <= n; ++i) arr[i] = lower_bound(brr + 1, brr + 1 + m, arr[i]) - brr;
 14 }
 15 
 16 int T[N];
 17 struct CHAIR
 18 {
 19     #define M N * 40
 20     int a[M], ls[M], rs[M], cnt;
 21     void build(int &id, int l, int r)
 22     {
 23         id = ++cnt;
 24         a[id] = 0;
 25         if (l == r) return;
 26         int mid = (l + r) >> 1;
 27         build(ls[id], l, mid);
 28         build(rs[id], mid + 1, r);
 29     }
 30     int update(int pre, int pos)
 31     {
 32         int now = ++cnt, tmp = now;
 33         a[now] = a[pre] + 1;
 34         int l = 1, r = m;
 35         while (l < r)
 36         {
 37             int mid = (l + r) >> 1;
 38             if (pos <= mid)
 39             {
 40                 ls[now] = ++cnt; rs[now] = rs[pre];
 41                 now = ls[now], pre = ls[pre]; 
 42                 r = mid;
 43             }
 44             else
 45             {
 46                 ls[now] = ls[pre], rs[now] = ++cnt;
 47                 now = rs[now], pre = rs[pre];
 48                 l = mid + 1;
 49             }
 50             a[now] = a[pre] + 1;
 51         }
 52         return tmp;
 53     }
 54     int query(int lt, int rt, int cnt)
 55     {
 56         lt = T[lt], rt = T[rt];
 57         int l = 1, r = m;
 58         while (l < r)
 59         {
 60             int mid = (l + r) >> 1;
 61             int szel = a[ls[rt]] - a[ls[lt]];
 62             int szer = a[rs[rt]] - a[rs[lt]];
 63             if (szel > cnt)
 64             {
 65                 lt = ls[lt];
 66                 rt = ls[rt];
 67                 r = mid;
 68             }
 69             else if (szer > cnt)
 70             {
 71                 lt = rs[lt];
 72                 rt = rs[rt];
 73                 l = mid + 1;
 74             }
 75             else
 76                 return 0;
 77         }
 78         return l;
 79     }
 80 }chair;
 81 
 82 
 83 void Run()
 84 {
 85     while (scanf("%d%d", &n, &q) != EOF)
 86     {
 87         for (int i = 1; i <= n; ++i) scanf("%d", arr + i); Hash();
 88         chair.build(T[0], 1, m);
 89         for (int i = 1; i <= n; ++i) T[i] = chair.update(T[i - 1], arr[i]);
 90         for (int i = 1, l, r; i <= q; ++i)
 91         {
 92             scanf("%d%d", &l, &r);
 93             printf("%d\n", brr[chair.query(l - 1, r, (r - l + 1) >> 1)]);
 94         }
 95     }
 96 }
 97 
 98 int main()
 99 {
100     #ifdef LOCAL
101         freopen("Test.in", "r", stdin);
102     #endif 
103 
104     Run();
105     return 0;
106 }
View Code

3578:集合Hash : 给每个点随机Hash权值,所有点权异或起来便是集合Hash值, 插入删除均是异或,然后线段树维护有效人数

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 int n, m, q, ran;
  6 int Hash[N], loc[N];
  7 map <int, bool> mp;
  8 
  9 struct SEG
 10 {
 11     int Set[N << 2], sum[N << 2], peo[N << 2], lazy[N << 2];
 12     void init()
 13     {
 14         memset(Set, 0, sizeof Set);
 15         memset(sum, 0, sizeof sum);
 16         memset(peo, 0, sizeof peo);
 17         memset(lazy, 0, sizeof lazy);
 18     }
 19     void pushup(int id) { sum[id] = sum[id << 1] + sum[id << 1 | 1]; }
 20     void clear(int id, int l, int r)
 21     {
 22         lazy[id] = 1; sum[id] = 0;
 23         if (l == r) 
 24             mp[Set[id]] = 1;
 25     }
 26     void pushdown(int id, int l, int r, int mid)
 27     {
 28         if (lazy[id])
 29         {
 30             if (l == r)
 31             {
 32                 lazy[id] = 0;
 33                 return;
 34             }
 35             clear(id << 1, l, mid);
 36             clear(id << 1 | 1, mid + 1, r);
 37             lazy[id] = 0; 
 38         }
 39     }
 40     void update(int id, int l, int r, int pos, int p, int val)
 41     {
 42         if (l == r)
 43         {
 44             Set[id] ^= p;
 45             peo[id] += val;  
 46             sum[id] = (mp.find(Set[id]) == mp.end() ? peo[id] : 0); 
 47             return;
 48         }
 49         int mid = (l + r) >> 1;
 50         pushdown(id, l, r, mid);
 51         if (pos <= mid) update(id << 1, l, mid, pos, p, val);
 52         else update(id << 1 | 1, mid + 1, r, pos, p, val);
 53         pushup(id);
 54     }
 55     
 56     int query(int id, int l, int r, int ql, int qr)
 57     {
 58         int res = 0;
 59         if (l >= ql && r <= qr)
 60         {
 61             res = sum[id]; 
 62             clear(id, l, r);  
 63             return res;   
 64         }
 65         int mid = (l + r) >> 1;
 66         pushdown(id, l, r, mid);
 67         if (ql <= mid) res += query(id << 1, l, mid, ql, qr);
 68         if (qr > mid) res += query(id << 1 | 1, mid + 1, r, ql, qr);
 69         pushup(id);
 70         return res;
 71     }
 72 }seg;
 73 
 74 void Run()
 75 {
 76     while (scanf("%d%d%d", &n, &m, &q) != EOF)
 77     {
 78         seg.init(); mp.clear();
 79         for (int i = 1; i <= n; ++i)
 80         {
 81             ran *= 233;
 82             ran += 17;  
 83             seg.update(1, 1, m, loc[i] = 1, Hash[i] = ran, 1);    
 84         }
 85         char op; int x, y;
 86         for (int i = 1; i <= q; ++i)
 87         {
 88             scanf(" %c%d%d", &op, &x, &y); 
 89             if (op == 'C')
 90             {
 91                 seg.update(1, 1, m, loc[x], Hash[x], -1); 
 92                 seg.update(1, 1, m, loc[x] = y, Hash[x], 1);
 93             }
 94             else
 95                 printf("%d\n", seg.query(1, 1, m, x, y));
 96         }
 97     }
 98 }
 99 
100 int main()
101 {
102     #ifdef LOCAL
103         freopen("Test.in", "r", stdin);
104     #endif 
105 
106     Run();
107     return 0;
108 }
View Code

3589:可持久化线段树+树剖

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3  
  4 #define N 200010
  5 #define ll long long
  6 ll const MOD = (ll)1ll << 31;  
  7 int n, q;
  8 struct Edge { int to, nx; }edge[N << 1];
  9 int head[N], cntedge;
 10 void addedge(int u, int v) { edge[++cntedge] = Edge{ v, head[u] }; head[u] = cntedge; }
 11 int p[N], lp[N], rp[N], sze[N], son[N], fa[N], deep[N], top[N], cntdfs;
 12  
 13 void DFS(int u)
 14 {
 15     sze[u] = 1;
 16     for (int it = head[u]; ~it; it = edge[it].nx)
 17     {
 18         int v = edge[it].to;
 19         if (v == fa[u]) continue;
 20         deep[v] = deep[u] + 1;
 21         fa[v] = u;
 22         DFS(v); sze[u] += sze[v];
 23         if (son[u] == -1 || sze[v] > sze[son[u]]) son[u] = v;
 24     }
 25 }
 26  
 27 void getpos(int u, int sp)
 28 {
 29     top[u] = sp; 
 30     p[u] = ++cntdfs; 
 31     lp[u] = cntdfs;
 32     if (son[u] == -1)
 33     {
 34         rp[u] = cntdfs;
 35         return;
 36     }
 37     getpos(son[u], sp); 
 38     for (int it = head[u]; ~it; it = edge[it].nx)
 39     {
 40         int v = edge[it].to; 
 41         if (v == fa[u] || v == son[u]) continue;
 42         getpos(v, v); 
 43     }
 44     rp[u] = cntdfs;
 45 }
 46  
 47 int T[5];
 48 struct SEG
 49 {
 50     #define M N * 60
 51     int cnt;
 52     struct node
 53     {
 54         int ls, rs, pre;
 55         ll sum, lazy;
 56         node() {}
 57         node(int ls, int rs, int pre, ll sum, ll lazy) : ls(ls), rs(rs), pre(pre), sum(sum), lazy(lazy) {}
 58     }a[M];
 59     void pushup(int id)
 60     {
 61         int ls = a[id].ls, rs = a[id].rs;
 62         a[id].sum = (a[ls].sum + a[rs].sum) % MOD;
 63     }
 64     void createson(int &now, int pre)
 65     {
 66         now = ++cnt; 
 67         a[now] = node(-1, -1, pre, 0, -1);  
 68         return;
 69     }
 70     void pushdown(int id, int l, int r)    
 71     { 
 72         if (a[id].lazy == 0) return; 
 73         int mid = (l + r) >> 1; 
 74         if (a[id].ls == -1 || a[id].rs == -1)
 75         {
 76             int pre = a[id].pre;
 77             createson(a[id].ls, a[pre].ls);
 78             createson(a[id].rs, a[pre].rs);
 79         }
 80         int ls = a[id].ls, rs = a[id].rs; 
 81         if (a[id].lazy == -1)
 82         {
 83             a[id].lazy = 0;
 84             a[ls].lazy = a[rs].lazy = -1;
 85             a[ls].sum = a[rs].sum = 0;
 86             return;
 87         }
 88         ll lazy = a[id].lazy; a[id].lazy = 0;   
 89         a[ls].lazy = (a[ls].lazy + lazy) % MOD; a[ls].sum = (a[ls].sum + lazy * (mid - l + 1) % MOD) % MOD;
 90         a[rs].lazy = (a[rs].lazy + lazy) % MOD; a[rs].sum = (a[rs].sum + lazy * (r - mid) % MOD) % MOD;
 91     } 
 92     void build(int &id, int l, int r)  
 93     {
 94         id = ++cnt; 
 95         a[id] = node(-1, -1, -1, 0, 0);
 96         if (l == r) return;
 97         int mid = (l + r) >> 1;
 98         build(a[id].ls, l, mid);
 99         build(a[id].rs, mid + 1, r);
100     } 
101     void update(int id, int l, int r, int ql, int qr, ll val)
102     {
103         if (l >= ql && r <= qr)
104         {
105             a[id].lazy = (a[id].lazy + val) % MOD;
106             a[id].sum = (a[id].sum + val * (r - l + 1) % MOD) % MOD;
107             return;
108         }
109         pushdown(id, l, r);
110         int mid = (l + r) >> 1;
111         if (ql <= mid) update(a[id].ls, l, mid, ql, qr, val);
112         if (qr > mid) update(a[id].rs, mid + 1, r, ql, qr, val);
113         pushup(id);
114     }
115     void update(int &now, int pre, int l, int r, int ql, int qr, ll val) 
116     {
117         now = ++cnt;
118         a[now] = node(-1, -1, pre, a[pre].sum, a[pre].lazy);  
119         if (l >= ql && r <= qr) 
120         {
121             a[now].lazy = -1;
122             a[now].sum = 0; 
123             return;
124         }
125         pushdown(pre, l, r);    
126         int mid = (l + r) >> 1;
127         if (ql <= mid) update(a[now].ls, a[pre].ls, l, mid, ql, qr, val);
128         else a[now].ls = a[pre].ls;  
129         if (qr > mid) update(a[now].rs, a[pre].rs, mid + 1, r, ql, qr, val);
130         else a[now].rs = a[pre].rs;
131         pushup(now);
132     }
133     ll query(int id, int l, int r, int ql, int qr)
134     {
135         if (l >= ql && r <= qr) return a[id].sum;
136         pushdown(id, l, r);  
137         int mid = (l + r) >> 1;
138         ll res = 0;
139         if (ql <= mid) res = (res + query(a[id].ls, l, mid, ql, qr)) % MOD;
140         if (qr > mid) res = (res + query(a[id].rs, mid + 1, r, ql, qr)) % MOD;
141         pushup(id);
142         return res;
143     }
144 }seg;
145  
146 ll query(int u, int v, int now)
147 {
148     ll res = 0;
149     while (top[u] != top[v])
150     {
151         if (deep[top[u]] < deep[top[v]]) swap(u, v); 
152         res = (res + seg.query(now, 1, n, p[top[u]], p[u])) % MOD;
153         u = fa[top[u]];
154     }
155     if (deep[u] > deep[v]) swap(u, v);
156     res = (res + seg.query(now, 1, n, p[u], p[v])) % MOD; 
157     return res;
158 }
159  
160 void update(int u, int v, int &now, int pre)    
161 {
162     while (top[u] != top[v])
163     {
164         if (deep[top[u]] < deep[top[v]]) swap(u, v);
165         seg.update(now, pre, 1, n, p[top[u]], p[u], 0); 
166         pre = now; 
167         u = fa[top[u]];
168     }
169     if (deep[u] > deep[v]) swap(u, v);
170     seg.update(now, pre, 1, n, p[u], p[v], 0); 
171 }  
172  
173 void init()
174 {
175     memset(head, -1, sizeof head);
176     memset(son, -1, sizeof son);
177     cntedge = 0;
178     cntdfs = 0;
179     seg.cnt = 0;  
180     seg.build(T[0], 1, n);
181 }
182  
183 void Run() 
184 {
185     while (scanf("%d", &n) != EOF)
186     {
187         init();
188         for (int i = 1, u, v; i < n; ++i)
189         {
190             scanf("%d%d", &u, &v);
191             addedge(u, v);
192             addedge(v, u);
193         }
194         DFS(1); getpos(1, 1); 
195         scanf("%d", &q);
196         for (int i = 1, op; i <= q; ++i)   
197         {
198             scanf("%d", &op);
199             if (op == 0)
200             {
201                 int u; ll x;
202                 scanf("%d%lld", &u, &x);   
203                 if (x == 0) continue;  
204                 seg.update(T[0], 1, n, lp[u], rp[u], x); 
205             }
206             else
207             {
208                 int k, u, v;
209                 scanf("%d", &k); 
210                 ll res = 0;
211                 int tmp = seg.cnt;   
212                 for (int j = 0; j < k; ++j)
213                 {
214                     scanf("%d%d", &u, &v);
215                     res = (res + query(u, v, T[j])) % MOD;  
216                     T[j + 1] = 0; 
217                     if (j != k - 1) update(u, v, T[j + 1], T[j]);  
218                 } 
219                 printf("%lld\n", res); 
220                 seg.cnt = tmp;
221             }
222         }
223     }
224 }
225  
226 int main()
227 {
228     #ifdef LOCAL
229         freopen("Test.in", "r", stdin);
230     #endif 
231  
232     Run();
233     return 0;
234 }
View Code

3626:差分+离线+树剖

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 50010
  5 int n, q;
  6 vector <int> G[N];
  7 struct qnode { int root, id, vis; };
  8 vector <qnode> que[N];
  9 int ans[N];
 10 int p[N], sze[N], son[N], top[N], deep[N], fa[N], cnt;
 11 
 12 void DFS(int u)
 13 {
 14     sze[u] = 1;
 15     for (int i = 0, len = G[u].size(); i < len; ++i)
 16     {
 17         int v = G[u][i];
 18         deep[v] = deep[u] + 1;
 19         fa[v] = u;
 20         DFS(v); sze[u] += sze[v];
 21         if (son[u] == -1 || sze[v] > sze[son[u]]) son[u] = v;
 22     }
 23 }
 24 
 25 void getpos(int u, int sp)
 26 {
 27     top[u] = sp;
 28     p[u] = ++cnt;
 29     if (son[u] == -1) return;
 30     getpos(son[u], sp);
 31     for (int i = 0, len = G[u].size(); i < len; ++i)
 32     {
 33         int v = G[u][i];
 34         if (v == son[u]) continue;
 35         getpos(v, v);
 36     }
 37 }
 38 
 39 struct SEG
 40 {
 41     int sum[N << 2], lazy[N << 2];
 42     void pushup(int id) { sum[id] = sum[id << 1] + sum[id << 1 | 1]; }
 43     void init()
 44     {
 45         memset(sum, 0, sizeof sum);
 46         memset(lazy, 0, sizeof lazy);
 47     }
 48     void pushdown(int id, int l, int r)
 49     {
 50         if (!lazy[id]) return;
 51         lazy[id << 1] += lazy[id];
 52         lazy[id << 1 | 1] += lazy[id];
 53         int mid = (l + r) >> 1;
 54         sum[id << 1] += lazy[id] * (mid - l + 1);   
 55         sum[id << 1 | 1] += lazy[id] * (r - mid);
 56         lazy[id] = 0;
 57     }
 58     void update(int id, int l, int r, int ql, int qr)
 59     {
 60         if (l >= ql && r <= qr)
 61         {
 62             sum[id] += (r - l + 1); 
 63             ++lazy[id];
 64             return;
 65         }
 66         pushdown(id, l, r);
 67         int mid = (l + r) >> 1;
 68         if (ql <= mid) update(id << 1, l, mid, ql, qr);
 69         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr);
 70         pushup(id);
 71     }
 72     int query(int id, int l, int r, int ql, int qr)
 73     {
 74         if (l >= ql && r <= qr) return sum[id];
 75         pushdown(id, l, r);
 76         int mid = (l + r) >> 1;
 77         int res = 0;
 78         if (ql <= mid) res += query(id << 1, l, mid, ql, qr);
 79         if (qr > mid) res += query(id << 1 | 1, mid + 1, r, ql, qr);
 80         pushup(id);
 81         return res;
 82     }
 83 }seg;
 84 
 85 void update(int u)
 86 {
 87     while (top[u] != 1)
 88     {
 89         seg.update(1, 1, n, p[top[u]], p[u]);
 90         u = fa[top[u]];
 91     }
 92     seg.update(1, 1, n, p[1], p[u]);
 93 }
 94 
 95 int query(int u)
 96 {
 97     int res = 0;
 98     while (top[u] != 1)
 99     {
100         res += seg.query(1, 1, n, p[top[u]], p[u]);
101         u = fa[top[u]];
102     }
103     res += seg.query(1, 1, n, p[1], p[u]);
104     return res;
105 }
106 
107 void init()
108 {
109     for (int i = 1; i <= n; ++i) G[i].clear(), que[i].clear();
110     memset(ans, 0, sizeof ans);
111     memset(son, -1, sizeof son);
112     seg.init();
113     cnt = 0;
114 }
115 
116 void Run() 
117 {
118     while (scanf("%d%d", &n, &q) != EOF)
119     {
120         init();
121         for (int i = 2, u; i <= n; ++i)
122         {
123             scanf("%d", &u); ++u;
124             G[u].push_back(i);
125         }
126         for (int i = 1, l, r, z; i <= q; ++i)
127         {
128             scanf("%d%d%d", &l, &r, &z); ++r; ++z;
129             que[l].push_back(qnode{ z, i, -1 });
130             que[r].push_back(qnode{ z, i, 1 });
131         }
132         DFS(1); getpos(1, 1);
133         for (int i = 1; i <= n; ++i)
134         {
135             update(i);
136             for (int j = 0, len = que[i].size(); j < len; ++j)
137             {
138                 int z = que[i][j].root, vis = que[i][j].vis, id = que[i][j].id;
139                 ans[id] += vis * query(z);
140             }
141         }
142         for (int i = 1; i <= q; ++i) printf("%d\n", ans[i] % 201314);
143     }
144 }
145 
146 int main()
147 {
148     #ifdef LOCAL
149         freopen("Test.in", "r", stdin);
150     #endif 
151 
152     Run();
153     return 0;
154 
155 }
View Code

3694:最短路树上枚举非树边+树剖

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 4010
  5 #define M 100010
  6 #define INF 0x3f3f3f3f
  7 int n, m;
  8 
  9 struct Graph
 10 {
 11     struct node
 12     {
 13         int to, nx, w, vis;
 14         node () {}
 15         node(int to, int nx, int w, int vis) : to(to), nx(nx), w(w), vis(vis) {}
 16     }a[M << 1]; int head[N], pos;
 17     void init()
 18     {
 19         memset(head, -1, sizeof head);
 20         pos = 0;
 21     }
 22     void add(int u, int v, int w, int vis)
 23     {
 24         a[++pos] = node(v, head[u], w, vis); head[u] = pos;
 25         a[++pos] = node(u, head[v], w, vis); head[v] = pos;
 26     }
 27 }G[2];
 28 #define erp(G, u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w, vis = G.a[it].vis; ~it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w, vis = G.a[it].vis)
 29 
 30 int fa[N], dis[N], deep[N], sze[N], son[N], top[N], p[N], fp[N], cnt;
 31 void DFS(int u)
 32 {
 33     sze[u] = 1;
 34     erp(G[1], u) if (v != fa[u])
 35     {
 36         fa[v] = u;
 37         dis[v] = dis[u] + w; 
 38         deep[v] = deep[u] + 1;
 39         DFS(v); sze[u] += sze[v];
 40         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
 41     } 
 42 }
 43 
 44 void getpos(int u, int sp)
 45 {
 46     top[u] = sp;
 47     p[u] = ++cnt;
 48     fp[cnt] = u;
 49     if (!son[u]) return;
 50     getpos(son[u], sp);
 51     erp(G[1], u) if (v != fa[u] && v != son[u])
 52         getpos(v, v);
 53 }
 54 
 55 struct SEG
 56 {
 57     int Min[N << 2];
 58     void build(int id, int l, int r)
 59     {
 60         Min[id] = INF;
 61         if (l == r) return;
 62         int mid = (l + r) >> 1;
 63         build(id << 1, l, mid);
 64         build(id << 1 | 1, mid + 1, r);
 65     }
 66     void update(int id, int l, int r, int ql, int qr, int val)
 67     {
 68         if (l >= ql && r <= qr)
 69         {
 70             Min[id] = min(Min[id], val);
 71             return;
 72         }
 73         int mid = (l + r) >> 1;
 74         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
 75         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
 76     }
 77     int query(int id, int l, int r, int pos)
 78     {
 79         if (l == r) return Min[id];
 80         int mid = (l + r) >> 1;
 81         int res = Min[id];
 82         if (pos <= mid) res = min(res, query(id << 1, l, mid, pos));
 83         else res = min(res, query(id << 1 | 1, mid + 1, r, pos));
 84         return res;
 85     }
 86 }seg;
 87 
 88 int querylca(int u, int v)
 89 {
 90     while (top[u] != top[v])
 91     {
 92         if (deep[top[u]] < deep[top[v]]) swap(u, v); 
 93         u = fa[top[u]];
 94     }
 95     if (deep[u] > deep[v]) swap(u, v);
 96     return u;
 97 }
 98 
 99 void update(int u, int v, int val)
100 {
101     if (u == v) return;
102     while (top[u] != top[v])
103     {
104         if (deep[top[u]] < deep[top[v]]) swap(u, v);
105         seg.update(1, 1, n, p[top[u]], p[u], val);
106         u = fa[top[u]];
107     }
108     if (u == v) return;
109     if (deep[u] > deep[v]) swap(u, v);
110     seg.update(1, 1, n, p[son[u]], p[v], val);
111 }
112 
113 void init()
114 {
115     memset(son, 0, sizeof son);
116     cnt = 0;
117     G[0].init(); G[1].init();
118 }
119 
120 void Run()
121 {
122     while (scanf("%d%d", &n, &m) != EOF)
123     {
124         init();
125         for (int i = 1, u, v, w, vis; i <= m; ++i)
126         {
127             scanf("%d%d%d%d", &u, &v, &w, &vis);
128             G[0].add(u, v, w, vis);
129             if (vis) G[1].add(u, v, w, vis);
130         } DFS(1); getpos(1, 1); seg.build(1, 1, n);
131         for (int i = 2; i <= n; ++i)
132         {
133             erp(G[0], i) if (!vis)
134             {
135                 int lca = querylca(i, v); 
136                 update(i, lca, dis[i] + dis[v] + w);  
137             } 
138         }
139         for (int i = 2; i <= n; ++i)
140         {
141             int res = seg.query(1, 1, n, p[i]); 
142             printf("%d%c", res == INF ? -1 : res - dis[i], " \n"[i == n]); 
143         }
144         
145     }
146 }
147 
148 int main()
149 {
150     #ifdef LOCAL
151         freopen("Test.in", "r", stdin);
152     #endif 
153 
154     Run();
155     return 0;
156 }
View Code

3744:分块+树状数组+主席树

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 50010
  5 #define block 250
  6 
  7 int n, m, q;
  8 int arr[N], brr[N], f[block + 10][N];
  9 
 10 struct BIT
 11 {
 12     int a[N];
 13     void init() { memset(a, 0, sizeof a); } 
 14     void update(int x, int val) { for (; x <= m; x += x & -x) a[x] += val; }
 15     int query(int x) { int res = 0; for (; x; x -= x & -x) res += a[x]; return res; }
 16 }bit;
 17 
 18 void Hash()
 19 {
 20     for (int i = 1; i <= n; ++i) brr[i] = arr[i];
 21     sort(brr + 1, brr + 1 + n);
 22     m = unique(brr + 1, brr + 1 + n) - brr - 1;
 23     for (int i = 1; i <= n; ++i) arr[i] = lower_bound(brr + 1, brr + 1 + m, arr[i]) - brr; 
 24 }
 25 
 26 struct CHAIR
 27 {
 28     #define M N * 50
 29     int T[N], L[M], R[M], C[M], cnt;
 30     void init(){ cnt = 0; }
 31     int build(int l, int r)
 32     {
 33         int root = cnt++;
 34         C[root] = 0;
 35         if (l < r)
 36         {
 37             int mid = (l + r) >> 1;
 38             L[root] = build(l, mid);
 39             R[root] = build(mid + 1, r);
 40         }
 41         return root;
 42     }
 43     int update(int root, int pos)
 44     {
 45         int newroot = cnt++, tmp = newroot;
 46         C[newroot] = C[root] + 1;
 47         int l = 1, r = m;
 48         while (l < r)
 49         {
 50             int mid = (l + r) >> 1;
 51             if (pos <= mid)
 52             {
 53                 L[newroot] = cnt++; R[newroot] = R[root];
 54                 newroot = L[newroot], root = L[root];
 55                 r = mid;
 56             }
 57             else
 58             {
 59                 L[newroot] = L[root], R[newroot] = cnt++;
 60                 newroot = R[newroot], root = R[root];
 61                 l = mid + 1;
 62             }
 63             C[newroot] = C[root] + 1;
 64         }
 65         return tmp;
 66     }
 67     int query(int left, int right, int pos)
 68     {
 69         int res = 0;
 70         int l = 1, r = m;
 71         while (l < r)
 72         {
 73             int mid = (l + r) >> 1;
 74             if (pos <= mid)
 75             {
 76                 left = L[left];
 77                 right = L[right];
 78                 r = mid;
 79             }
 80             else
 81             {
 82                 res += C[L[right]] - C[L[left]];
 83                 left = R[left];
 84                 right = R[right];
 85                 l = mid + 1;
 86             }
 87         }
 88         return res; 
 89     }
 90 }chair;
 91 
 92 void Run()
 93 {
 94     while (scanf("%d", &n) != EOF)
 95     {
 96         for (int i = 1; i <= n; ++i) scanf("%d", arr + i); Hash();
 97         for (int i = 1; (i - 1) * block + 1 <= n; ++i) 
 98         {
 99             int st = (i - 1) * block + 1;
100             bit.init();  
101             for (int j = st; j <= n; ++j)   
102             {
103                 bit.update(arr[j], 1);
104                 f[i][j] = f[i][j - 1] + (j - st + 1) - bit.query(arr[j]);  
105             }
106         }
107         chair.T[0] = chair.build(1, m);
108         for (int i = 1; i <= n; ++i) chair.T[i] = chair.update(chair.T[i - 1], arr[i]);   
109         scanf("%d", &q);  bit.init();
110         int res = 0;
111         for (int i = 1, l, r; i <= q; ++i)
112         {
113             scanf("%d%d", &l, &r);
114             l ^= res, r ^= res;
115             res = 0;
116             if ((l - 1) / block == (r - 1) / block)
117             {
118                 for (int j = l; j <= r; ++j)
119                 {
120                     bit.update(arr[j], 1);
121                     res += (j - l + 1) - bit.query(arr[j]);
122                 }
123                 for (int j = l; j <= r; ++j) bit.update(arr[j], -1); 
124             }
125             else
126             {
127                 int nx = (l - 1) / block + 1; 
128                 res += f[nx + 1][r];  
129                 for (int j = l; j <= nx * block; ++j) res += chair.query(chair.T[j], chair.T[r], arr[j]); 
130             }
131             printf("%d\n", res);
132         }
133     }
134 }
135 
136 int main()
137 {
138     #ifdef LOCAL
139         freopen("Test.in", "r", stdin);
140     #endif 
141 
142     Run();
143     return 0;
144 }
View Code

3809:莫队+分块

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 #define block 450
 6 
 7 int n, q;
 8 int arr[N];
 9 struct qnode
10 {
11     int l, r, a, b, id;
12     void scan(int id) { this->id = id; scanf("%d%d%d%d", &l, &r, &a, &b); }
13     bool operator < (const qnode &r) const
14     {
15         int posl = l / block, posr = r.l / block;
16         return posl == posr ? this->r < r.r : posl < posr;
17     }
18 }que[N * 10]; int ans[N * 10];
19 
20 int cnt[N], cntblock[block]; 
21 void update(int x, int val)
22 {
23     if (val == 1)
24     {
25         if (cnt[arr[x]] == 0) ++cntblock[(arr[x] - 1) / block];
26         ++cnt[arr[x]];
27     }
28     else
29     {
30         if (cnt[arr[x]] == 1) --cntblock[(arr[x] - 1) / block];
31         --cnt[arr[x]];
32     }
33 }
34 
35 int query(int l, int r)
36 {
37     int posl = (l - 1) / block, posr = (r - 1) / block;
38     int res = 0;
39     if (posl == posr)
40     {
41         for (int i = l; i <= r; ++i) if (cnt[i])
42             ++res;
43     }
44     else
45     {
46         for (int i = l; i <= (posl + 1) * block; ++i) if (cnt[i])
47             ++res;
48         for (int i = posl + 1; i < posr; ++i)
49             res += cntblock[i];
50         for (int i = posr * block + 1; i <= r; ++i) if (cnt[i])
51             ++res;
52     }
53     return res;
54 }
55 
56 void Run()
57 {
58     while (scanf("%d%d", &n, &q) != EOF)
59     {
60         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
61         for (int i = 1; i <= q; ++i) que[i].scan(i); 
62         sort(que + 1, que + 1 + q);
63         memset(cnt, 0, sizeof cnt); 
64         memset(cntblock, 0, sizeof cntblock);
65         for (int i = 1, l = 1, r = 0; i <= q; ++i)
66         {
67             for (; r < que[i].r; ++r) update(r + 1, 1);
68             for (; r > que[i].r; --r) update(r, -1);
69             for (; l < que[i].l; ++l) update(l, -1);
70             for (; l > que[i].l; --l) update(l - 1, 1);
71             ans[que[i].id] = query(que[i].a, que[i].b);
72         }
73         for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
74     }
75 }
76 
77 int main()
78 {
79     #ifdef LOCAL
80         freopen("Test.in", "r", stdin);
81     #endif 
82 
83     Run();
84     return 0;
85 }
View Code

3910:树剖

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define N 500010
  6 
  7 int n, q, st;
  8 vector <int> G[N];
  9 int arr[N];
 10 
 11 struct SEG
 12 {
 13     struct node
 14     {
 15         int l, r, vis, lazy;  
 16         node() {}
 17         node(int l, int r)
 18         {
 19             this->l = l;
 20             this->r = r;  
 21             vis = lazy = 0;
 22         }
 23     }a[N << 2];
 24     void pushdown(int id) 
 25     {
 26         if (a[id].lazy)
 27         {
 28             a[id].lazy = 0; 
 29             a[id << 1].vis = 1;
 30             a[id << 1].lazy = 1;
 31             a[id << 1 | 1].vis = 1;
 32             a[id << 1 | 1].lazy = 1;
 33         }
 34     }
 35     void build(int id, int l, int r)
 36     {
 37         a[id] = node(l, r);
 38         if (l == r) return; 
 39         int mid = (l + r) >> 1;
 40         build(id << 1, l, mid);
 41         build(id << 1 | 1, mid + 1, r); 
 42     }
 43     void update(int id, int l, int r)
 44     {
 45         if (a[id].l >= l && a[id].r <= r)
 46         {
 47             a[id].vis = 1;
 48             a[id].lazy = 1;  
 49             return;
 50         }
 51         pushdown(id); 
 52         int mid = (a[id].l + a[id].r) >> 1;
 53         if (l <= mid) update(id << 1, l, r);
 54         if (r > mid) update(id << 1 | 1, l, r); 
 55     } 
 56     int query(int id, int pos)
 57     {
 58         if (a[id].l == a[id].r) return a[id].vis;
 59         pushdown(id); 
 60         int mid = (a[id].l + a[id].r) >> 1;
 61         return (pos <= mid ? query(id << 1, pos) : query(id << 1 | 1, pos));
 62     } 
 63 }seg;
 64 
 65 int p[N], fp[N], sze[N], son[N], top[N], fa[N], deep[N], cnt;
 66 void DFS(int u)
 67 {
 68     sze[u] = 1; 
 69     for (int i = 0, v, len = G[u].size(); i < len; ++i)
 70     {
 71         v = G[u][i];
 72         if (v != fa[u])
 73         {
 74             fa[v] = u;
 75             deep[v] = deep[u] + 1;
 76             DFS(v);
 77             sze[u] += sze[v]; 
 78             if (son[u] == -1 || sze[v] > sze[son[u]]) son[u] = v;
 79         }
 80     }
 81 }
 82 
 83 void getpos(int u, int sp)
 84 {
 85     top[u] = sp; 
 86     p[u] = ++cnt;
 87     fp[cnt] = u;
 88     if (son[u] == -1) return;  
 89     getpos(son[u], sp);   
 90     for (int i = 0, v, len = G[u].size(); i < len; ++i)
 91     {
 92         v = G[u][i]; 
 93         if (v != fa[u] && v != son[u])  
 94             getpos(v, v);   
 95     }
 96 }
 97 
 98 int modify(int u, int v)
 99 {
100     int fu = top[u], fv = top[v]; 
101     while (fu != fv)
102     {
103         if (deep[fu] < deep[fv])
104         {
105             swap(fu, fv);
106             swap(u, v);
107         }
108         seg.update(1, p[fu], p[u]); 
109         u = fa[fu]; fu = top[u];
110     }
111     if (u == v) return u;
112     if (deep[u] > deep[v]) swap(u, v); 
113     seg.update(1, p[u], p[v]);
114     return u;
115 }
116 
117 void Run()
118 {
119     while (scanf("%d%d%d", &n, &q, &st) != EOF) 
120     {
121         seg.build(1, 1, n); 
122         memset(son, -1, sizeof son);  
123         cnt = 0;
124         for (int i = 1; i <= n; ++i) G[i].clear();
125         for (int i = 1, u, v; i < n; ++i)
126         {
127             scanf("%d%d", &u, &v);
128             G[u].push_back(v); 
129             G[v].push_back(u);
130         }
131         for (int i = 1; i <= q; ++i) scanf("%d", arr + i);
132         DFS(1); getpos(1, 1);       
133         ll res = 0;
134         for (int i = 1; i <= q; ++i)
135         {
136             if (seg.query(1, p[arr[i]]) == 0)
137             {
138                 int LCA = modify(st, arr[i]);
139                 res += deep[st] + deep[arr[i]] - 2 * deep[LCA]; 
140                 st = arr[i];
141             }
142         }
143         printf("%lld\n", res);  
144     }
145 }
146 
147 int main()
148 {
149     #ifdef LOCAL
150         freopen("Test.in", "r", stdin); 
151     #endif 
152 
153     Run();
154     return 0;
155 
156 }
View Code

4012:树剖+可持久化线段树(标记永久化)

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3  
  4 #define N 150010
  5 #define ll long long
  6 #define pii pair <int, int> 
  7 int n, q, a[N], age[N]; ll A;
  8 ll sum[N];
  9  
 10 struct Graph
 11 {
 12     struct node
 13     {
 14         int to, nx; int w;
 15         node() {}
 16         node(int to, int nx, int w) : to(to), nx(nx), w(w) {}
 17     }a[N << 1];
 18     int head[N], pos;
 19     void Init() { memset(head, 0, sizeof head); pos = 0; }
 20     void add(int u, int v, int w)
 21     {
 22         a[++pos] = node(v, head[u], w); head[u] = pos;
 23         a[++pos] = node(u, head[v], w); head[v] = pos;
 24     }
 25 }G;
 26 #define erp(u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w; it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w)
 27  
 28 ll dis[N], arr[N], prefix[N]; 
 29 int p[N], fp[N], fa[N], deep[N], sze[N], son[N], top[N], cnt;
 30 void DFS(int u)
 31 {
 32     sze[u] = 1;
 33     erp(u) if (v != fa[u])
 34     {
 35         fa[v] = u;  
 36         deep[v] = deep[u] + 1;
 37         dis[v] = dis[u] + w;
 38         arr[v] = w; 
 39         DFS(v); sze[u] += sze[v];
 40         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
 41     }
 42 }
 43  
 44 void getpos(int u, int sp) 
 45 {
 46     top[u] = sp;
 47     p[u] = ++cnt;
 48     fp[cnt] = u;
 49     if (!son[u]) return;
 50     getpos(son[u], sp);
 51     erp(u) if (v != fa[u] && v != son[u])
 52         getpos(v, v); 
 53 }
 54  
 55 int T[N];
 56 struct SEG
 57 {
 58     #define M N * 75
 59     struct node
 60     {
 61         int ls, rs; ll lazy, sum;  
 62         node() {}  
 63         node (int ls, int rs, ll lazy, ll sum) : ls(ls), rs(rs), lazy(lazy), sum(sum) {}
 64     }a[M]; int cnt; 
 65     void build(int &now, int l, int r)
 66     {
 67         now = ++cnt;
 68         a[now] = node(-1, -1, 0, 0);
 69         if (l == r) return;  
 70         int mid = (l + r) >> 1; 
 71         build(a[now].ls, l, mid);
 72         build(a[now].rs, mid + 1, r);
 73     }
 74     void update(int &now, int pre, int l, int r, int ql, int qr)
 75     {  
 76         now = ++cnt;
 77         a[now] = a[pre];
 78         a[now].sum += prefix[qr] - prefix[ql - 1];
 79         if (l >= ql && r <= qr)  
 80         {
 81             ++a[now].lazy;  
 82             return;
 83         }
 84         int mid = (l + r) >> 1;
 85         if (ql <= mid) update(a[now].ls, a[pre].ls, l, mid, ql, min(mid, qr));
 86         if (qr > mid) update(a[now].rs, a[pre].rs, mid + 1, r, max(mid + 1, ql), qr);
 87     } 
 88     ll query(int lt, int rt, int l, int r, int ql, int qr)
 89     {
 90         if (l >= ql && r <= qr) return a[rt].sum - a[lt].sum;    
 91         int mid = (l + r) >> 1;  
 92         ll res = (a[rt].lazy - a[lt].lazy) * (prefix[qr] - prefix[ql - 1]);  
 93         if (ql <= mid) res += query(a[lt].ls, a[rt].ls, l, mid, ql, min(mid, qr));  
 94         if (qr > mid) res += query(a[lt].rs, a[rt].rs, mid + 1, r, max(mid + 1, ql), qr);
 95         return res;
 96     }   
 97 }seg;
 98  
 99 void update(int u, int v, int &now, int pre) 
100 {
101     now = pre; 
102     while (top[u] != top[v])
103     {
104         if (deep[top[u]] < deep[top[v]]) swap(u, v);
105         seg.update(now, pre, 1, n, p[top[u]], p[u]);
106         pre = now;  
107         u = fa[top[u]];
108     } 
109     if (u == v) return; 
110     if (deep[u] > deep[v]) swap(u, v);
111     seg.update(now, pre, 1, n, p[son[u]], p[v]); 
112 }
113  
114 ll query(int u, int v, int lt, int rt)
115 { 
116     ll res = 0;
117     while (top[u] != top[v])
118     {
119         if (deep[top[u]] < deep[top[v]]) swap(u, v);
120         res += seg.query(lt, rt, 1, n, p[top[u]], p[u]); 
121         u = fa[top[u]];
122     }
123     if (u == v) return res;
124     if (deep[u] > deep[v]) swap(u, v); 
125     return res + seg.query(lt, rt, 1, n, p[son[u]], p[v]); 
126 } 
127  
128 bool cmp(int a, int b) { return age[a] < age[b]; }
129  
130 void init()
131 {
132     G.Init(); cnt = 0; dis[1] = 0; deep[1] = 0;
133     seg.cnt = 0; sum[0] = 0; arr[1] = 0;
134     memset(son, 0, sizeof son);
135 } 
136  
137 void Run()
138 {
139     while (scanf("%d%d%lld", &n, &q, &A) != EOF)
140     {
141         init();
142         for (int i = 1; i <= n; ++i) scanf("%d", age + i), a[i] = i;
143         sort(a + 1, a + 1 + n, cmp); 
144         sort(age + 1, age + 1 + n);
145         for (int i = 1, u, v, w; i < n; ++i)
146         {
147             scanf("%d%d%d", &u, &v, &w);
148             G.add(u, v, w); 
149         }
150         DFS(1); getpos(1, 1); 
151         seg.build(T[0], 1, n); 
152         for (int i = 1; i <= n; ++i) prefix[i] = prefix[i - 1] + arr[fp[i]];
153         for (int i = 1; i <= n; ++i) 
154         {
155             update(1, a[i], T[i], T[i - 1]);  
156             sum[i] = sum[i - 1] + dis[a[i]];  
157         }
158         ll res = 0; int u; ll l, r; 
159         for (int i = 1; i <= q; ++i)
160         {
161             scanf("%d%lld%lld", &u, &l, &r);
162             l = (l + res) % A; 
163             r = (r + res) % A;
164             if (l > r) swap(l, r);  
165             int ql = lower_bound(age + 1, age + 1 + n, l) - age;  
166             int qr = upper_bound(age + 1, age + 1 + n, r) - age - 1; 
167             if (ql > qr) res = 0;  
168             else
169             {
170                 res = sum[qr] - sum[ql - 1] + dis[u] * (qr - ql + 1); 
171                 res -= 2 * query(1, u, T[ql - 1], T[qr]);  
172             }
173             printf("%lld\n", res); res %= A;
174         }
175     }
176 }
177  
178 int main()
179 {
180     Run();
181     return 0;
182 }
View Code

4236:考虑拆成两个等式判断L, R是否满足,再借助map快速找答案

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 200010
 5 int n, pos[N], J[N], O[N], I[N]; 
 6 char s[N];
 7 map <int, int> mp[N]; 
 8 int Hasharr[N], m;
 9 
10 void Hash()
11 {
12     for (int i = 0; i <= n; ++i) Hasharr[i] = pos[i];
13     sort(Hasharr, Hasharr + 1 + n);
14     m = unique(Hasharr, Hasharr + 1 + n) - Hasharr;
15     for (int i = 0; i <= n; ++i) pos[i] = lower_bound(Hasharr, Hasharr + 1 + m, pos[i]) - Hasharr;
16 }
17 
18 void Run()
19 {
20     while (scanf("%d", &n) != EOF)
21     {
22         scanf("%s", s + 1);  
23         for (int i = 1; i <= n; ++i) 
24         {
25             J[i] = J[i - 1];
26             O[i] = O[i - 1];
27             I[i] = I[i - 1];
28             if (s[i] == 'J') ++J[i];
29             else if (s[i] == 'O') ++O[i]; 
30             else ++I[i];
31         }
32         for (int i = 0; i <= n; ++i) pos[i] = J[i] - O[i];  Hash();
33         int res = 0;
34         for (int i = 0; i <= n; ++i)  
35         {
36             int need = O[i] - I[i]; 
37             if (mp[pos[i]].find(need) != mp[pos[i]].end())
38                 res = max(res, i - mp[pos[i]][need]);   
39             else
40                 mp[pos[i]][need] = i;
41         }
42         printf("%d\n", res);
43     }
44 }
45 
46 int main()
47 {
48     #ifdef LOCAL
49         freopen("Test.in", "r", stdin);
50     #endif 
51 
52     Run();
53     return 0;
54 }
View Code

4260:可持久化trie+DP

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 400010
 5 int n;
 6 int arr[N], dp[N];
 7 
 8 int T[N];
 9 struct TRIE
10 {
11     struct node
12     {
13         int son[2], cnt;
14     }a[N * 50]; int cnt;
15     void Insert(int &now, int pre, int x)
16     {
17         bitset <32> b; b = x;
18         now = ++cnt;
19         a[now] = a[pre];
20         int root = now;
21         for (int i = 31; i >= 0; --i)
22         {
23             a[++cnt] = a[a[root].son[b[i]]];  
24             ++a[cnt].cnt; 
25             a[root].son[b[i]] = cnt;
26             root = cnt; 
27         }
28     }
29     int query(int lt, int rt, int x)
30     {
31         bitset <32> b; b = x;
32         lt = T[lt], rt = T[rt];
33         int res = 0;
34         for (int i = 31; i >= 0; --i)
35         {
36             int id = b[i] ^ 1;
37             bool flag = true;
38             if (a[a[rt].son[id]].cnt - a[a[lt].son[id]].cnt <= 0)
39             {
40                 flag = false;
41                 id ^= 1;
42             }
43             if (flag) res += 1 << i;
44             lt = a[lt].son[id];
45             rt = a[rt].son[id];
46         }
47         return res;
48     }
49 }trie;
50 
51 void Run()
52 {
53     while (scanf("%d", &n) != EOF)
54     {
55         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
56         for (int i = 1; i <= n; ++i) arr[i] ^= arr[i - 1];
57         trie.cnt = 0; trie.Insert(T[0], T[0], 0);  
58         for (int i = 1; i <= n; ++i) trie.Insert(T[i], T[i - 1], arr[i]); 
59         for (int i = n; i >= 1; --i) dp[i] = max(dp[i + 1], trie.query(i - 1, n, arr[i - 1]));
60         int res = 0;
61         for (int i = 1; i <= n; ++i)
62             res = max(res, trie.query(0, i, arr[i]) + dp[i + 1]);
63         printf("%d\n", res);
64     }
65 }
66 
67 int main()
68 {
69     #ifdef LOCAL
70         freopen("Test.in", "r", stdin);
71     #endif 
72 
73     Run();
74     return 0;
75 }
View Code

4291:考虑如何构造偶数

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 #define ll long long
 5 #define N 1000010
 6  
 7 int n;
 8  
 9 void Run()
10 {
11     while (scanf("%d", &n) != EOF)
12     {
13         ll res = 0; int cnt = 0, Min = 0x3f3f3f3f;
14         for (int i = 1, num; i <= n; ++i)
15         {
16             scanf("%d", &num);
17             if (num & 1)
18             {
19                 ++cnt;
20                 Min = min(Min, num);
21             }
22             res += num;
23         }
24         if (cnt & 1) res -= Min;
25         if (res == 0)
26         {
27             puts("NIESTETY");
28             continue;
29         }
30         printf("%lld\n", res);
31          
32     }
33 }
34  
35 int main()
36 {
37     #ifdef LOCAL
38         freopen("Test.in", "r", stdin); 
39     #endif 
40  
41     Run();
42     return 0;
43  
44 }
View Code

4300:对每一位考虑,$b[i] And b[i - 1] != 0$ 即至少有一位都是1

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int n, arr[N], Max[32];
 6 
 7 void Run()
 8 {
 9     while (scanf("%d", &n) != EOF)
10     {
11         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
12         memset(Max, 0, sizeof Max);
13         int ans = 0;
14         for (int i = 1; i <= n; ++i) 
15         {
16             bitset <32> b; b = arr[i];
17             int res = 0;
18             for (int j = 31; j >= 0; --j) if (b[j])
19                 res = max(res, Max[j]); 
20             ans = max(res + 1, ans);
21             for (int j = 31; j >= 0; --j) if (b[j])
22                 Max[j] = max(Max[j], res + 1);
23         }
24         printf("%d\n", ans);
25     }
26 }
27 
28 int main()
29 {
30     #ifdef LOCAL
31         freopen("Test.in", "r", stdin);
32     #endif 
33 
34     Run();
35     return 0;
36 }
View Code

4326:二分+树剖+线段树

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define N 300010
  6 #define pii pair <int, int> 
  7 int n, m;  
  8 vector <pii> G[N]; pii que[N];
  9 struct Edge { int u, v; ll w; Edge() {} Edge(int u, int v, ll w) : u(u), v(v), w(w) {} } edge[N];
 10 int p[N], fp[N], fa[N], deep[N], sze[N], son[N], top[N], cnt;   
 11 ll dis[N], arr[N];     
 12 
 13 void DFS(int u) 
 14 {
 15     sze[u] = 1;
 16     for (int i = 0, len = G[u].size(); i < len; ++i) 
 17     { 
 18         int v = G[u][i].first; 
 19         if (v == fa[u]) continue;  
 20         fa[v] = u; 
 21         deep[v] = deep[u] + 1; 
 22         dis[v] = dis[u] + G[u][i].second;  
 23         DFS(v); sze[u] += sze[v]; 
 24         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
 25     }
 26 }
 27 
 28 void getpos(int u, int sp) 
 29 {
 30     top[u] = sp;
 31     p[u] = ++cnt;           
 32     fp[cnt] = u;
 33     if (!son[u]) return; 
 34      getpos(son[u], sp);
 35     for (int i = 0, len = G[u].size(); i < len; ++i)
 36     {
 37         int v = G[u][i].first;
 38         if (v == fa[u] || v == son[u]) continue;
 39         getpos(v, v);
 40     }
 41 }
 42 
 43 struct SEG
 44 {
 45     int a[N << 2], lazy[N << 2];
 46     void Init()
 47     {
 48         memset(a, 0, sizeof a);
 49         memset(lazy, 0, sizeof lazy);  
 50     }
 51     void pushdown(int id, int l, int r, int mid)
 52     {
 53         if (!lazy[id]) return;
 54         lazy[id << 1] += lazy[id];  
 55         a[id << 1] += lazy[id] * (mid - l + 1);  
 56         lazy[id << 1 | 1] += lazy[id];
 57         a[id << 1 | 1] += lazy[id] * (r - mid);
 58         lazy[id] = 0;
 59     }
 60     void pushup(int id) { a[id] = a[id << 1] + a[id << 1 | 1]; }
 61     void update(int id, int l, int r, int ql, int qr)
 62     {
 63         if (l >= ql && r <= qr)
 64         {
 65             a[id] += r - l + 1;
 66             ++lazy[id]; 
 67             return;
 68         }
 69         int mid = (l + r) >> 1;
 70         pushdown(id, l, r, mid);
 71         if (ql <= mid) update(id << 1, l, mid, ql, qr);
 72         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr);
 73         pushup(id);
 74     }
 75     int query(int id, int l, int r, int pos)
 76     {
 77         if (l == r) return a[id];
 78         int mid = (l + r) >> 1;
 79         pushdown(id, l, r, mid);
 80         int res = 0;
 81         if (pos <= mid) res = query(id << 1, l, mid, pos);
 82         else res = query(id << 1 | 1, mid + 1, r, pos);
 83         pushup(id);
 84         return res;
 85     }
 86 }seg; 
 87 
 88 int querylca(int u, int v)
 89 {
 90     while (top[u] != top[v])
 91     {
 92         if (deep[top[u]] < deep[top[v]]) swap(u, v);
 93         u = fa[top[u]];  
 94     }
 95     if (deep[u] > deep[v]) swap(u, v);
 96     return u;
 97 }
 98 
 99 void update(int u, int v)
100 {
101     while (top[u] != top[v]) 
102     {
103         if (deep[top[u]] < deep[top[v]]) swap(u, v);
104         seg.update(1, 1, n, p[top[u]], p[u]);   
105         u = fa[top[u]];   
106     }
107     if (u == v) return;  
108     if (deep[u] > deep[v]) swap(u, v);  
109     seg.update(1, 1, n, p[son[u]], p[v]);    
110 }
111  
112 bool check(ll x)
113 {
114     seg.Init(); vector <ll> vec;     
115     for (int i = 1; i <= m; ++i)   
116     {
117         int u = que[i].first, v = que[i].second;
118         ll tot = dis[u] + dis[v] - 2 * dis[querylca(u, v)];
119         if (tot <= x) continue;  
120         update(u, v);  
121         vec.push_back(tot); 
122     }
123     ll Max = -1; int tot = vec.size(); 
124     if (tot == 0) return true;  
125     for (int i = 2; i <= n; ++i) if (seg.query(1, 1, n, i) == tot)  
126         Max = max(Max, arr[fp[i]]);  
127     if (Max == -1) return false; 
128     for (int i = 0; i < tot; ++i)   
129         if (vec[i] - Max > x) return false;  
130     return true; 
131 }  
132 
133 void Run()
134 {
135     while (scanf("%d%d", &n, &m) != EOF) 
136     {
137         ll tot = 0; 
138         for (int i = 1, u, v, w; i < n; ++i)
139         {
140             scanf("%d%d%d", &u, &v, &w);  
141             edge[i] = Edge(u, v, w);
142             G[u].push_back(pii(v, w)); 
143             G[v].push_back(pii(u, w));  
144             tot += w;
145         }
146         for (int i = 1; i <= m; ++i) 
147             scanf("%d%d", &que[i].first, &que[i].second);   
148         DFS(1); getpos(1, 1);    
149         for (int i = 1; i < n; ++i)
150         {
151             if (fa[edge[i].v] != edge[i].u) swap(edge[i].u, edge[i].v); 
152             arr[edge[i].v] = edge[i].w;  
153         } 
154         ll l = 0, r = tot, res = tot; 
155         while (r - l >= 0)
156         {
157             ll mid = (l + r) >> 1;    
158             if (check(mid))
159             {
160                 res = mid;
161                 r = mid - 1;
162             }
163             else
164                 l = mid + 1;
165         }
166         printf("%lld\n", res); 
167     }
168 }
169 
170 int main()
171 {
172     #ifdef LOCAL
173         freopen("Test.in", "r", stdin);
174     #endif 
175 
176     Run();
177     return 0;
178 }
View Code

4397:前缀

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int n, q;
 6 int sum[3][N];
 7 
 8 void Run()
 9 {
10     while (scanf("%d%d", &n, &q) != EOF)
11     {
12         memset(sum, 0, sizeof sum);
13         for (int i = 1, x; i <= n; ++i)
14         {
15             scanf("%d", &x);
16             ++sum[x - 1][i];
17             for (int j = 0; j < 3; ++j)
18                 sum[j][i] += sum[j][i - 1];
19         }
20         for (int i = 1, l, r; i <= q; ++i)
21         {
22             scanf("%d%d", &l, &r);
23             for (int j = 0; j < 3; ++j)
24                 printf("%d%c", sum[j][r] - sum[j][l - 1], " \n"[j == 2]);
25         }
26     }
27 }
28 
29 int main()
30 {
31     #ifdef LOCAL
32         freopen("Test.in", "r", stdin);
33     #endif 
34 
35     Run();
36     return 0;
37 }
View Code

4423:对偶图+并查集 建图需要多建一圈

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 1510
 5 int n, q, S, ans;
 6 int pos[N][N], pre[N * N];
 7 
 8 int find(int x) { return pre[x] == 0 ? x : pre[x] = find(pre[x]); }
 9 
10 void Run()
11 {
12     while (scanf("%d%d", &n, &q) != EOF)
13     {
14         memset(pre, 0, sizeof pre);
15         S = (n - 1) * (n - 1) + 1;
16         for (int i = 1; i <= n + 1; ++i) for (int j = 1; j <= n + 1; ++j) pos[i][j] = S;
17         for (int i = 2, tot = 0; i <= n; ++i) for (int j = 2; j <= n; ++j) pos[i][j] = ++tot; 
18         char op; int a, b, x, y; ans = 0; 
19         while (q--)
20         {
21             scanf("%d%d %c", &a, &b, &op);
22             if (ans) scanf("%d%d %c", &a, &b, &op);
23             if (op == 'N') x = pos[a][b + 1], y = pos[a + 1][b + 1];
24             else x = pos[a + 1][b], y = pos[a + 1][b + 1];
25             if (!ans) scanf("%d%d %c", &a, &b, &op);
26             int fx = find(x), fy = find(y);
27             ans = fx == fy; 
28             if (!ans) pre[fx] = fy; 
29             puts(ans ? "NIE" : "TAK");   
30         }
31     }
32 }
33 
34 int main()
35 {
36     #ifdef LOCAL
37         freopen("Test.in", "r", stdin);
38     #endif 
39 
40     Run();
41     return 0;
42 }
View Code

4448:可持久化线段树+树链剖分

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 200010
  5 #define pii pair <int, int>
  6 int n, q;
  7 vector <int> G[N];
  8 int p[N], fp[N], sze[N], fa[N], deep[N], top[N], son[N], cnt;
  9 
 10 void DFS(int u)
 11 {
 12     sze[u] = 1;
 13     for (int i = 0, len = G[u].size(); i < len; ++i)
 14     {
 15         int v = G[u][i];
 16         if (v == fa[u]) continue;
 17         fa[v] = u; deep[v] = deep[u] + 1;
 18         DFS(v); sze[u] += sze[v];
 19         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
 20     }
 21 }
 22 
 23 void getpos(int u, int sp)
 24 {
 25     top[u] = sp;
 26     p[u] = ++cnt;
 27     fp[cnt] = u;
 28     if (!son[u]) return;
 29     getpos(son[u], sp);
 30     for (int i = 0, len = G[u].size(); i < len; ++i)
 31     {
 32         int v = G[u][i];
 33         if (v == fa[u] || v == son[u]) continue;
 34         getpos(v, v);
 35     }
 36 }
 37 
 38 int T[N];
 39 struct SEG 
 40 {
 41     #define M N * 40
 42     int a[M], ls[M], rs[M], cnt;
 43     void build(int &id, int l, int r)
 44     {
 45         id = ++cnt;
 46         a[id] = 0;
 47         if (l == r) return;
 48         int mid = (l + r) >> 1;
 49         build(ls[id], l, mid);
 50         build(rs[id], mid + 1, r);
 51     } 
 52     void pushup(int id) { a[id] = a[ls[id]] + a[rs[id]]; }
 53     void update(int &now, int pre, int l, int r, int pos)
 54     {
 55         now = ++cnt;
 56         a[now] = a[pre]; ls[now] = ls[pre]; rs[now] = rs[pre];
 57         if (l == r)
 58         {
 59             ++a[now];
 60             return;
 61         }
 62         int mid = (l + r) >> 1;
 63         if (pos <= mid) update(ls[now], ls[pre], l, mid, pos);
 64         else update(rs[now], rs[pre], mid + 1, r, pos);
 65         pushup(now);
 66     }
 67     int query(int now, int l, int r, int ql, int qr)
 68     {
 69         if (l >= ql && r <= qr) return a[now];
 70         int mid = (l + r) >> 1;
 71         int res = 0;
 72         if (ql <= mid) res += query(ls[now], l, mid, ql, qr);
 73         if (qr > mid) res += query(rs[now], mid + 1, r, ql, qr);
 74         return res;
 75     }
 76 }seg;
 77 
 78 pii query(int u, int v, int c)
 79 {
 80     int res = 0;
 81     while (top[u] != top[v])
 82     {
 83         if (deep[top[u]] < deep[top[v]])
 84             swap(u, v);
 85         res += seg.query(T[c], 1, n, p[top[u]], p[u]);
 86         u = fa[top[u]]; 
 87     }
 88     if (deep[u] > deep[v]) swap(u, v);
 89     res += seg.query(T[c], 1, n, p[u], p[v]);
 90     return pii(u, res);
 91 }
 92 
 93 void Run()
 94 {
 95     while (scanf("%d", &n) != EOF)
 96     {
 97         for (int i = 1, u; i <= n; ++i)
 98         {
 99             scanf("%d", &u);
100             if (u)
101             {
102                 G[u].push_back(i);
103                 G[i].push_back(u);
104             }
105         }
106         DFS(1); getpos(1, 1);
107         seg.build(T[0], 1, n);
108         scanf("%d", &q);
109         int op, x, y, c;
110         for (int i = 1; i <= q; ++i)
111         {
112             scanf("%d%d", &op, &x);
113             if (op == 2) seg.update(T[i], T[i - 1], 1, n, p[x]);
114             else
115             {
116                 T[i] = T[i - 1]; 
117                 scanf("%d%d", &y, &c);
118                 pii res = query(x, y, max(0, i - c - 1)); 
119                 res.first = deep[x] + deep[y] - 2 * deep[res.first] + 1;
120                 printf("%d %d\n", res.first, res.second);
121             }
122         }
123     }
124 }
125 
126 int main()
127 {
128     #ifdef LOCAL
129         freopen("Test.in", "r", stdin);
130     #endif 
131 
132     Run();
133     return 0;
134 }
View Code

4551:树剖

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define N 100010 
  6 
  7 int n, q;
  8 vector <int> G[N];
  9 
 10 struct SEG
 11 {
 12     int Max[N << 2];
 13     void pushup(int id) { Max[id] = max(Max[id << 1], Max[id << 1 | 1]); }
 14     void build(int id, int l, int r)
 15     {
 16         Max[id] = 0;
 17         if (l == r) return;
 18         int mid = (l + r) >> 1;
 19         build(id << 1, l, mid);
 20         build(id << 1 | 1, mid + 1, r);
 21     }
 22     void update(int id, int l, int r, int pos)
 23     {
 24         if (l == r)
 25         {
 26             Max[id] = pos;
 27             return;
 28         }
 29         int mid = (l + r) >> 1;
 30         pos <= mid ? update(id << 1, l, mid, pos) : update(id << 1 | 1, mid + 1, r, pos);
 31         pushup(id);
 32     }
 33     int query(int id, int l, int r, int ql, int qr)
 34     {
 35         if (l >= ql && r <= qr) return Max[id];
 36         int mid = (l + r) >> 1, res = 0;
 37         if (ql <= mid) res = max(res, query(id << 1, l, mid, ql, qr));
 38         if (qr > mid) res = max(res, query(id << 1 | 1, mid + 1, r, ql, qr));
 39         return res;
 40     }
 41 }seg;
 42 
 43 int p[N], fp[N], sze[N], son[N], top[N], fa[N], deep[N], cnt;
 44 void DFS(int u)
 45 {
 46     sze[u] = 1; 
 47     for (int i = 0, v, len = G[u].size(); i < len; ++i)
 48     {
 49         v = G[u][i];
 50         if (v != fa[u])
 51         {
 52             fa[v] = u;
 53             deep[v] = deep[u] + 1;
 54             DFS(v);
 55             sze[u] += sze[v]; 
 56             if (son[u] == -1 || sze[v] > sze[son[u]]) son[u] = v;
 57         }
 58     }
 59 }
 60 
 61 void getpos(int u, int sp)
 62 {
 63     top[u] = sp; 
 64     p[u] = ++cnt;
 65     fp[cnt] = u;
 66     if (son[u] == -1) return;  
 67     getpos(son[u], sp);   
 68     for (int i = 0, v, len = G[u].size(); i < len; ++i)
 69     {
 70         v = G[u][i]; 
 71         if (v != fa[u] && v != son[u])  
 72             getpos(v, v);   
 73     }
 74 }
 75 
 76 int query(int u, int v)
 77 {
 78     int fu = top[u], fv = top[v]; 
 79     int res = 0;
 80     while (fu != fv)
 81     {
 82         if (deep[fu] < deep[fv])
 83         {
 84             swap(fu, fv);
 85             swap(u, v);
 86         }
 87         res = max(res, seg.query(1, 1, n, p[fu], p[u])); 
 88         u = fa[fu]; fu = top[u];
 89     }
 90     if (deep[u] > deep[v]) swap(u, v); 
 91     res = max(res, seg.query(1, 1, n, p[u], p[v])); 
 92     return res;
 93 }
 94 
 95 void Run()
 96 {
 97     while (scanf("%d%d", &n, &q) != EOF) 
 98     {
 99         seg.build(1, 1, n); 
100         memset(son, -1, sizeof son);  
101         cnt = 0; 
102         for (int i = 1; i <= n; ++i) G[i].clear();
103         for (int i = 1, u, v; i < n; ++i)
104         {
105             scanf("%d%d", &u, &v);
106             G[u].push_back(v); 
107             G[v].push_back(u);
108         }
109         DFS(1); getpos(1, 1);       
110         seg.update(1, 1, n, 1);
111         char op;
112         for (int i = 1, u; i <= q; ++i)
113         {
114             scanf(" %c%d", &op, &u);
115             if (op == 'Q') printf("%d\n", fp[query(u, 1)]); 
116             else seg.update(1, 1, n, p[u]);
117         }
118     }
119 }
120 
121 int main()
122 {
123     #ifdef LOCAL
124         freopen("Test.in", "r", stdin); 
125     #endif 
126 
127     Run();
128     return 0;
129 
130 }
View Code

4552:二分答案+线段树 考虑把 >x 的数标为0,<x 的数标为1

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 int n, m, q;
  6 int arr[N];
  7 
  8 struct qnode
  9 {
 10     int op, l, r;
 11     void scan() { scanf("%d%d%d", &op, &l, &r); }
 12 }que[N];
 13 
 14 struct SEG
 15 {
 16     int lazy[N << 2], sum[N << 2];
 17     void init()
 18     {
 19         memset(lazy, -1, sizeof lazy);
 20         memset(sum, 0, sizeof sum);
 21     }
 22     void pushup(int id) { sum[id] = sum[id << 1] + sum[id << 1 | 1]; }
 23     void pushdown(int id, int l, int r, int mid)
 24     {
 25         if (lazy[id] == -1) return;
 26         lazy[id << 1] = lazy[id];
 27         sum[id << 1] = lazy[id] * (mid - l + 1);
 28         lazy[id << 1 | 1] = lazy[id];
 29         sum[id << 1 | 1] = lazy[id] * (r - mid);
 30         lazy[id] = -1;
 31     }
 32     void update(int id, int l, int r, int ql, int qr, int val)
 33     {
 34         if (ql > qr) return;
 35         if (l >= ql && r <= qr)
 36         {
 37             lazy[id] = val;
 38             sum[id] = val * (r - l + 1);
 39             return;
 40         }
 41         int mid = (l + r) >> 1;
 42         pushdown(id, l, r, mid);
 43         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
 44         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
 45         pushup(id);
 46     }
 47     int query(int id, int l, int r, int ql, int qr)
 48     {
 49         if (l >= ql && r <= qr) return sum[id];
 50         int mid = (l + r) >> 1;
 51         pushdown(id, l, r, mid);
 52         int res = 0;
 53         if (ql <= mid) res += query(id << 1, l, mid, ql, qr);
 54         if (qr > mid) res += query(id << 1 | 1, mid + 1, r, ql, qr);
 55         pushup(id);
 56         return res;
 57     }
 58 }seg;
 59 
 60 bool check(int x)
 61 {
 62     seg.init();
 63     for (int i = 1; i <= n; ++i)
 64         seg.update(1, 1, n, i, i, arr[i] > x);
 65     for (int i = 1; i <= m; ++i)
 66     {
 67         int l = que[i].l, r = que[i].r; 
 68         int cnt_one = seg.query(1, 1, n, l, r), cnt_zero = (r - l + 1) - cnt_one;
 69         if (que[i].op == 0)
 70         {
 71             seg.update(1, 1, n, l, l + cnt_zero - 1, 0);
 72             seg.update(1, 1, n, l + cnt_zero, r, 1);
 73         }
 74         else
 75         {
 76             seg.update(1, 1, n, l, l + cnt_one - 1, 1);
 77             seg.update(1, 1, n, l + cnt_one, r, 0); 
 78         }
 79     }
 80     return !seg.query(1, 1, n, q, q); 
 81 }
 82 
 83 void Run()
 84 {
 85     while (scanf("%d%d", &n, &m) != EOF)
 86     {
 87         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
 88         for (int i = 1; i <= m; ++i) que[i].scan();
 89         scanf("%d", &q);
 90         int l = 1, r = n, res = 0;
 91         while (r - l >= 0)
 92         {
 93             int mid = (l + r) >> 1;
 94             if (check(mid))
 95             {
 96                 res = mid;
 97                 r = mid - 1;
 98             }
 99             else
100                 l = mid + 1;
101         }
102         printf("%d\n", res);
103     }
104 }
105 
106 int main()
107 {
108     #ifdef LOCAL
109         freopen("Test.in", "r", stdin);
110     #endif 
111 
112     Run();
113     return 0;
114 }
View Code

4553:将一个点拆分成两个,找不等关系,CDQ分治

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 
  6 struct node
  7 {
  8     int v, Max, Min;
  9     void scan()
 10     {
 11         scanf("%d", &v);
 12         Max = Min = v;
 13     }
 14     void update()
 15     {
 16         int tmp;
 17         scanf("%d", &tmp);
 18         Max = max(Max, tmp); 
 19         Min = min(Min, tmp);
 20     }
 21 }arr[N];
 22 
 23 struct qnode
 24 {
 25     int op, x, y, id; 
 26     qnode() {}
 27     qnode(int op, int id, int x, int y) : op(op), id(id), x(x), y(y) {}
 28     bool operator < (const qnode &r) const { return x == r.x ? (y == r.y ? (id == r.id ? op > r.op : id < r.id) : y < r.y) : x < r.x; } 
 29 }q[N << 1], tq[N << 1];  
 30 
 31 struct BIT
 32 {
 33     int a[N];
 34     void init() { memset(a, 0, sizeof a); }
 35     void update(int x, int val) { for (; x < N; x += x & -x) a[x] = max(a[x], val); }
 36     int query(int x) { int res(0); for (; x; x -= x & -x) res = max(res, a[x]); return res; }
 37     void clear(int x) { for (; x < N; x += x & -x) a[x] = 0; }    
 38 }bit;
 39 
 40 int n, m, res; 
 41 int dp[N]; 
 42 
 43 void CDQ(int l, int r)
 44 {
 45     if (l >= r) return;
 46     int mid = (l + r) >> 1;
 47     CDQ(l, mid);
 48     for (int i = l; i <= r; ++i) 
 49     {
 50         tq[i] = q[i];
 51         if (i <= mid)
 52         {
 53             if (tq[i].op == 1)
 54                 tq[i].op = 0;
 55             else
 56                 tq[i].op = 3;
 57         }
 58     } 
 59     sort(tq + l, tq + r + 1); 
 60     for (int i = l; i <= r; ++i)
 61     {
 62         if (!tq[i].op) bit.update(tq[i].y, dp[tq[i].id]);  
 63         else if (tq[i].op == 2) dp[tq[i].id] = max(dp[tq[i].id], bit.query(tq[i].y) + 1);   
 64     }
 65     for (int i = l; i <= r; ++i) if (!tq[i].op) bit.clear(tq[i].y);  
 66     CDQ(mid + 1, r);  
 67 }
 68 
 69 
 70 void Run()
 71 {
 72     while (scanf("%d%d", &n, &m) != EOF)
 73     {
 74         bit.init();
 75         for (int i = 1; i <= n; ++i) dp[i] = 1;
 76         for (int i = 1; i <= n; ++i) arr[i].scan(); 
 77         for (int i = 1, x; i <= m; ++i)
 78         {
 79             scanf("%d", &x); 
 80             arr[x].update();
 81         } 
 82         for (int i = 1; i <= n; ++i) 
 83         { 
 84             q[(i << 1) - 1] = qnode(2, i, arr[i].Min, arr[i].v); 
 85             q[i << 1] = qnode(1, i, arr[i].v, arr[i].Max); 
 86         }
 87         CDQ(1, n << 1); res = 1; 
 88         for (int i = 1; i <= n; ++i) res = max(res, dp[i]);
 89         printf("%d\n", res); 
 90     }
 91 }
 92 
 93 int main()
 94 {
 95     #ifdef LOCAL
 96         freopen("Test.in", "r", stdin);
 97     #endif 
 98 
 99     Run();
100     return 0;
101 }
View Code

4999:树链剖分+线段树 (离散化后对每一个x开线段树,动态开点)

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 100010
  5 #define M 3500010
  6 
  7 int n, m, q;
  8 int arr[N], brr[N << 2];
  9 vector <int> G[N];
 10 
 11 int Get(int x)
 12 {
 13     return lower_bound(brr + 1, brr + 1 + m, x) - brr;
 14 }
 15 
 16 struct QUE
 17 {
 18     int op, u, v, x;
 19     void scan()
 20     {
 21         char s[10];
 22         scanf("%s", s);
 23         if (s[0] == 'Q')
 24         {
 25             op = 0;
 26             scanf("%d%d%d", &u, &v, &x);
 27             brr[++m] = x;  
 28         }
 29         else
 30         {
 31             op = 1;
 32             scanf("%d%d", &u, &x);
 33             brr[++m] = x;
 34         }
 35     }
 36 }que[N << 1];
 37 
 38 int top[N], num[N], deep[N], fa[N], son[N], p[N], fp[N], pos;
 39 
 40 void DFS(int u)
 41 {
 42     num[u] = 1;
 43     for (int i = 0, len = G[u].size(); i < len; ++i) 
 44     {
 45         int v = G[u][i];
 46         if (v == fa[u]) continue;
 47         deep[v] = deep[u] + 1;
 48         fa[v] = u;
 49         DFS(v); num[u] += num[v];
 50         if (son[u] == -1 || num[v] > num[son[u]])
 51             son[u] = v; 
 52     }
 53 }
 54 
 55 void getpos(int u, int sp) 
 56 {
 57     top[u] = sp;
 58     p[u] = ++pos;
 59     fp[pos] = u;
 60     if (son[u] == -1) return;
 61     getpos(son[u], sp);
 62     for (int i = 0, len = G[u].size(); i < len; ++i)
 63     {
 64         int v = G[u][i];
 65         if (v != son[u] && v != fa[u])
 66             getpos(v, v);
 67     }
 68 }
 69 
 70 struct SEG
 71 {
 72     int T[N << 2], lson[M], rson[M], c[M], cnt;
 73     
 74     void pushup(int id)
 75     {
 76         c[id] = c[lson[id]] + c[rson[id]];
 77     }
 78 
 79     void update(int &x, int l, int r, int pos, int val)
 80     {
 81         if (!x)
 82         {
 83             x = ++cnt;
 84             lson[x] = rson[x] = c[x] = 0;
 85         }
 86         if (l == r)
 87         {
 88             c[x] += val;
 89             return;
 90         }
 91         int mid = (l + r) >> 1;
 92         if (pos <= mid) update(lson[x], l, mid, pos, val);
 93         else update(rson[x], mid + 1, r, pos, val);
 94         pushup(x);
 95     }
 96 
 97     int query(int x, int l, int r, int ql, int qr)
 98     {
 99         if (l >= ql && r <= qr) return c[x];
100         int mid = (l + r) >> 1;
101         int res = 0;
102         if (ql <= mid) res += query(lson[x], l, mid, ql, qr);
103         if (qr > mid) res += query(rson[x], mid + 1, r, ql, qr);
104         return res;
105     }
106     
107 }segtree;
108 
109 int query(int u, int v, int x)
110 {
111     int fu = top[u], fv = top[v];
112     x = segtree.T[x];
113     int res = 0;
114     while (fu != fv)
115     {
116         if (deep[fu] < deep[fv])
117         {
118             swap(u, v);
119             swap(fu, fv);
120         }
121         res += segtree.query(x, 1, n, p[fu], p[u]);
122         u = fa[fu];
123         fu = top[u];
124     }
125     if (deep[u] > deep[v]) swap(u, v);
126     res += segtree.query(x, 1, n, p[u], p[v]);
127     return res;
128 }
129 
130 void Run()
131 {
132     while (scanf("%d%d", &n, &q) != EOF)
133     {
134         m = 0; fa[1] = 1; deep[1] = 0; pos = 0; 
135         memset(son, -1, sizeof son);
136         for (int i = 1; i <= n; ++i) scanf("%d", arr + i), brr[++m] = arr[i];
137         for (int i = 1, u, v; i < n; ++i)
138         {
139             scanf("%d%d", &u, &v);
140             G[u].push_back(v);
141             G[v].push_back(u);
142         } DFS(1); getpos(1, 1);
143         for (int i = 1; i <= q; ++i) que[i].scan();
144         sort(brr + 1, brr + 1 + m);
145         m = unique(brr + 1, brr + 1 + m) - brr - 1;  
146         for (int i = 1; i <= n; ++i) arr[i] = Get(arr[i]); 
147         for (int i = 1; i <= q; ++i) que[i].x = Get(que[i].x);
148         for (int i = 1; i <= n; ++i) segtree.update(segtree.T[arr[i]], 1, n, p[i], 1);  
149         for (int i = 1; i <= q; ++i)
150         {
151             if (que[i].op == 0)
152                 printf("%d\n", query(que[i].u, que[i].v, que[i].x));
153             else
154             {
155                 int u = que[i].u, x = que[i].x;
156                 segtree.update(segtree.T[arr[u]], 1, n, p[u], -1);  
157                 arr[u] = x;
158                 segtree.update(segtree.T[arr[u]], 1, n, p[u], 1);
159             }
160         }
161     }
162 }
163 
164 int main()
165 {
166     #ifdef LOCAL
167         freopen("Test.in", "r", stdin);
168     #endif
169 
170     Run();
171     return 0;
172 }
View Code

5204:水。

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int t, n, m, a[N], b[N], cnt[N];
 6 
 7 void Hash()
 8 {
 9     for (int i = 1; i <= n; ++i) b[i] = a[i];
10     sort(b + 1, b + 1 + n);
11     m = unique(b + 1, b + 1 + n) - b - 1;
12     for (int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + 1 + m, a[i]) - b;
13 }
14 
15 bool ok()
16 {
17     for (int i = 2; i <= m; ++i) if (cnt[i] != cnt[i - 1])
18         return true;
19     return false; 
20 }
21 
22 void Run()
23 {
24     scanf("%d", &t);
25     while (t--)
26     {
27         scanf("%d", &n);
28         memset(cnt, 0, sizeof cnt);
29         for (int i = 1; i <= n; ++i) scanf("%d", a + i); Hash();
30         for (int i = 1; i <= n; ++i) ++cnt[a[i]];
31         if (!ok()) puts("-1");
32         else
33         {
34             int Max = *max_element(cnt + 1, cnt + 1 + m);
35             int tot = 0;
36             for (int i = 1; i <= m; ++i) if (cnt[i] == Max)
37                 ++tot;
38             printf("%d\n", tot);
39             for (int i = 1, j = 0; i <= m; ++i) if (cnt[i] == Max)
40                 printf("%d%c", b[i], " \n"[(++j) == tot]);
41         }
42     }
43 }
44 
45 int main()
46 {
47     #ifdef LOCAL
48         freopen("Test.in", "r", stdin);
49     #endif 
50 
51     Run();
52     return 0;
53 }
View Code

5293:lca+前缀点权和

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3  
 4 #define ll long long
 5 #define N 300010
 6 const ll MOD = (ll)998244353;
 7 int n, q;
 8 vector <int> G[N];
 9 int p[N], fp[N], deep[N], fa[N], sze[N], top[N], son[N], cnt;
10 ll dis[N][55];
11  
12 void DFS(int u)
13 {
14     sze[u] = 1;
15     for (int i = 0, len = G[u].size(); i < len; ++i) 
16     {
17         int v = G[u][i];
18         if (v == fa[u]) continue;
19         fa[v] = u; deep[v] = deep[u] + 1;
20         dis[v][1] = deep[v];
21         dis[v][0] = 1;
22         for (int i = 2; i <= 50; ++i)
23             dis[v][i] = (dis[v][i - 1] * deep[v]) % MOD;
24         for (int i = 0; i <= 50; ++i)
25             dis[v][i] = (dis[v][i] + dis[u][i]) % MOD;
26         DFS(v); sze[u] += sze[v];  
27         if (son[u] == -1 || sze[v] > sze[son[u]]) son[u] = v;
28     }
29 }
30  
31 void getpos(int u, int sp)
32 {
33     top[u] = sp;
34     p[u] = ++cnt;
35     fp[cnt] = u;
36     if (son[u] == -1) return; 
37     getpos(son[u], sp); 
38     for (int i = 0, len = G[u].size(); i < len; ++i) 
39     {
40         int v = G[u][i];
41         if (v == fa[u] || v == son[u]) continue;
42         getpos(v, v);
43     }
44 }
45  
46 int querylca(int u, int v)
47 {
48     while (top[u] != top[v])
49     {
50         if (deep[top[u]] < deep[top[v]])
51             swap(u, v);
52         u = fa[top[u]];
53     }
54     if (deep[u] > deep[v]) swap(u, v);
55     return u;
56 }
57  
58  
59 void Init()
60 {
61     for (int i = 1; i <= n; ++i) G[i].clear();
62     memset(son, -1, sizeof son);
63     cnt = 0; dis[1][0] = 1;
64 }
65  
66 void Run()
67 {
68     while (scanf("%d", &n) != EOF)
69     {
70         Init();
71         for (int i = 1, u, v; i < n; ++i)
72         {
73             scanf("%d%d", &u, &v);
74             G[u].push_back(v);
75             G[v].push_back(u);
76         }
77         DFS(1); getpos(1, 1);
78         scanf("%d", &q);
79         for (int i = 1, u, v, k; i <= q; ++i)
80         {
81             scanf("%d%d%d", &u, &v, &k);
82             int lca = querylca(u, v);
83             printf("%lld\n", (dis[u][k] + dis[v][k] - dis[lca][k] - dis[fa[lca]][k] + 2 * MOD) % MOD); 
84         }
85     }
86 }
87  
88 int main()
89 {
90     #ifdef LOCAL
91         freopen("Test.in", "r", stdin);
92     #endif 
93  
94     Run();
95     return 0;
96 }
View Code

5301:莫队

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 #define unit 450
 6 #define ll long long 
 7 
 8 struct qnode
 9 {
10     int l, r, id;
11     void scan(int id)
12     {
13         scanf("%d%d", &l, &r); --l;
14         this->id = id;
15     }
16     bool operator < (const qnode &r) const
17     {
18         int posl = l / unit, posr = r.l / unit;
19         return posl < posr || posl == posr && this->r < r.r;
20     }
21 }que[N];
22 int n, m, k, a[N], ans[N], cnt[N];
23 ll res;
24 
25 void add(int x)
26 {
27     if (x == -1) return;
28     int pos = a[x] ^ k;
29     res += cnt[pos];
30     ++cnt[a[x]];
31 }
32 
33 void del(int x)
34 {
35     if (x == -1) return;
36     int pos = a[x] ^ k;
37     --cnt[a[x]];
38     res -= cnt[pos];
39 }
40 
41 void Run()
42 {
43     while (scanf("%d%d%d", &n, &m, &k) != EOF)
44     {
45         memset(cnt, 0, sizeof cnt); 
46         for (int i = 1; i <= n; ++i) scanf("%d", a + i), a[i] ^= a[i - 1];
47         for (int i = 1; i <= m; ++i) que[i].scan(i);
48         sort(que + 1, que + 1 + m); cnt[0] = 1;
49         for (int i = 1, l = 0, r = 0; i <= m; ++i)
50         {
51             for (; r < que[i].r; ++r) add(r + 1);  
52             for (; r > que[i].r; --r) del(r);
53             for (; l < que[i].l; ++l) del(l); 
54             for (; l > que[i].l; --l) add(l - 1);
55             ans[que[i].id] = res;
56         }
57         for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
58     }
59 }
60 
61 int main()
62 {
63     #ifdef LOCAL
64         freopen("Test.in", "r", stdin);
65     #endif 
66 
67     Run();
68     return 0;
69 }
View Code

5313:循环节

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int f[30];
 5 
 6 void Run()
 7 {
 8     f[1] = 1, f[2] = 1;
 9     for (int i = 3; i < 30; ++i) f[i] = (f[i - 1] + f[i - 2]) % 5;
10     int q, x;
11     while (scanf("%d", &q) != EOF)
12     {
13         while (q--)
14         {
15             scanf("%d", &x);
16             printf("%d\n", f[(x - 1) % 20 + 1]); 
17         }
18     }
19 }
20 
21 int main()
22 {
23     #ifdef LOCAL
24         freopen("Test.in", "r", stdin);
25     #endif 
26 
27     Run();
28     return 0;
29 }
View Code

5338:树剖+可持久化Trie

BZOJ 一句话题解_#ifdefBZOJ 一句话题解_#ifdef_02
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3  
  4 #define N 100010
  5 int n, q;
  6 int arr[N];
  7 vector <int> G[N];
  8 int p[N], fp[N], lp[N], rp[N], sze[N], son[N], top[N], deep[N], fa[N], cnt;
  9  
 10 void DFS(int u)
 11 {
 12     sze[u] = 1;
 13     for (int i = 0, len = G[u].size(); i < len; ++i)
 14     {
 15         int v = G[u][i];
 16         if (v == fa[u]) continue;
 17         fa[v] = u; deep[v] = deep[u] + 1;
 18         DFS(v); sze[u] += sze[v];
 19         if (son[u] == -1 || sze[v] > sze[son[u]]) son[u] = v;
 20     }
 21 }
 22  
 23 void getpos(int u, int sp)
 24 {
 25     top[u] = sp;
 26     p[u] = ++cnt;
 27     fp[cnt] = u;
 28     lp[u] = cnt;
 29     if (son[u] == -1)
 30     {
 31         rp[u] = cnt;
 32         return;
 33     }
 34     getpos(son[u], sp);
 35     for (int i = 0, len = G[u].size(); i < len; ++i)
 36     {
 37         int v = G[u][i];
 38         if (v == fa[u] || v == son[u]) continue;
 39         getpos(v, v);
 40     }
 41     rp[u] = cnt;
 42 }
 43  
 44 int T[N];
 45 struct TRIE
 46 {
 47     struct node
 48     {
 49         int son[2], cnt;
 50         node() { memset(son, 0, sizeof son); cnt = 0; }
 51     }a[N * 50]; int cnt;
 52     void Init()
 53     {
 54         a[1] = node();
 55         cnt = 0;
 56     }
 57     void Insert(int now, int pre, int val)
 58     {
 59         bitset <30> b; b = val;
 60         T[now] = ++cnt;  
 61         pre = T[pre]; 
 62         now = T[now];
 63         a[now] = a[pre]; 
 64         for (int i = 29; i >= 0; --i)
 65         {
 66             a[++cnt] = a[a[now].son[b[i]]];  
 67             ++a[cnt].cnt;
 68             a[now].son[b[i]] = cnt;
 69             now = cnt;
 70         }  
 71     }
 72     int query(int lt, int rt, int val)
 73     {
 74         bitset <30> b; b = val;
 75         lt = T[lt], rt = T[rt];
 76         int res = 0;
 77         for (int i = 29; i >= 0; --i)
 78         {
 79             int id = b[i] ^ 1;
 80             bool flag = true;
 81             if (a[a[rt].son[id]].cnt - a[a[lt].son[id]].cnt <= 0) 
 82             {
 83                 id ^= 1;
 84                 flag = false;
 85             }
 86             if (flag) res += 1 << i;
 87             rt = a[rt].son[id];
 88             lt = a[lt].son[id];
 89         }
 90         return res;
 91     }
 92 }trie;
 93  
 94 int query(int u, int v, int x)
 95 {
 96     int res = 0;
 97     while (top[u] != top[v])
 98     {
 99         if (deep[top[u]] < deep[top[v]])
100             swap(u, v);
101         res = max(res, trie.query(p[top[u]] - 1, p[u], x));
102         u = fa[top[u]];
103     }
104     if (deep[u] > deep[v]) swap(u, v);
105     res = max(res, trie.query(p[u] - 1, p[v], x));
106     return res;
107 }
108  
109 void Init()
110 {
111     memset(son, -1, sizeof son);
112     trie.Init();
113 }
114  
115 void Run()
116 {
117     while (scanf("%d%d", &n, &q) != EOF)
118     {
119         Init();
120         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
121         for (int i = 1, u, v; i < n; ++i)
122         {
123             scanf("%d%d", &u, &v);
124             G[u].push_back(v);
125             G[v].push_back(u);
126         }
127         DFS(1); getpos(1, 1);
128         for (int i = 1; i <= n; ++i) trie.Insert(i, i - 1, arr[fp[i]]);
129         for (int i = 1, op, x, y, z; i <= q; ++i)
130         {
131             scanf("%d%d%d", &op, &x, &y);
132             if (op == 1) printf("%d\n", trie.query(lp[x] - 1, rp[x], y));
133             else
134             {
135                 scanf("%d", &z);
136                 printf("%d\n", query(x, y, z));
137             }
138         }
139     }
140 }
141  
142 int main()
143 {
144     #ifdef LOCAL
145         freopen("Test.in", "r", stdin);
146     #endif 
147  
148     Run();
149     return 0;
150 }
View Code

end.