zoukankan      html  css  js  c++  java
  • BZOJ 一句话题解

    菜鸡刷题记录

     [题号:题解]


    1008:简单排列组合

     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
    ", (qmod(m, n) - (m % MOD * qmod(m - 1, n - 1) % MOD) + MOD) % MOD);
    24     return 0;
    25 }
    View Code

    1012:BIT维护后缀最大

     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
    ", 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缩点

     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
    ", Run());
    78     }
    79     return 0;
    80 }
    View Code

    1086:树分块

     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
    ", cnt);
    54         for (int i = 1; i <= n; ++i) printf("%d%c", Belong[i], " 
    "[i == n]);
    55         for (int i = 1; i <= cnt; ++i) printf("%d%c", cap[i], " 
    "[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:模拟+优先队列,主要不要暴力枚举时间

     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
    ", 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:差分+坑 有重复

     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
    ", h + ans[i]);
    26     }
    27     return 0;
    28 }
    View Code

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

     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
    ", 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

      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
    ", 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

     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
    ", res);    
    16         else 
    17         {
    18             printf("%llu", res / 10);
    19             puts("6");
    20         }
    21     }
    22     return 0;
    23 }
    View Code

    2120:带修改莫队

      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
    ", 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:分块+树状数组

     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
    ", 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
    ", 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:树剖+线段树

      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
    ", seg.res.sum);
    187                 else if (op[1] == 'I') printf("%d
    ", seg.res.Min);
    188                 else printf("%d
    ", seg.res.Max);
    189             }
    190         }
    191     }
    192     return 0;
    193 }
    View Code

    2286:虚数+树形DP

      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
    ", 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()

     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
    ", res);
    58     }    
    59     return 0;
    60 }
    View Code

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

      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
    ", 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:先排男生和老师,老师相邻和不相邻,相邻的话需要插入一个女生

     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:整体二分

      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
    ", ans[i]);
    100     }
    101     return 0;
    102 }
    View Code

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

      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
    ", 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:线段树维护,注意区间的合并

      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
    ", 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:单调队列维护左端点,枚举右端点

     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
    ", 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:整体二分+线段树

      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
    ", 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:硬核线段树

     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
    ", 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+二分

     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
    ", 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加入形成四关键字排序使得排序顺序固定,然后前后各扫一遍更新最大答案

     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
    ", 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

      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
    ", 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优化才过的,应该不是正解。

      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 == '
    ' || ch == '
    ' || ch == '	';
     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('
    '); }
    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:主席树

      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
    ", 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值, 插入删除均是异或,然后线段树维护有效人数

      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
    ", 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:可持久化线段树+树剖

      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
    ", 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:差分+离线+树剖

      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
    ", 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:最短路树上枚举非树边+树剖

      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], " 
    "[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:分块+树状数组+主席树

      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
    ", 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:莫队+分块

     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
    ", 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:树剖

      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
    ", 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:树剖+可持久化线段树(标记永久化)

      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
    ", res); res %= A;
    174         }
    175     }
    176 }
    177  
    178 int main()
    179 {
    180     Run();
    181     return 0;
    182 }
    View Code

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

     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
    ", 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

     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
    ", 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:考虑如何构造偶数

     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
    ", 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

     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
    ", 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:二分+树剖+线段树

      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
    ", 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:前缀

     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], " 
    "[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:对偶图+并查集 建图需要多建一圈

     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:可持久化线段树+树链剖分

      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
    ", 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:树剖

      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
    ", 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

      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
    ", 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分治

      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
    ", 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开线段树,动态开点)

      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
    ", 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:水。

     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
    ", tot);
    39             for (int i = 1, j = 0; i <= m; ++i) if (cnt[i] == Max)
    40                 printf("%d%c", b[i], " 
    "[(++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+前缀点权和

     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
    ", (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:莫队

     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
    ", 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:循环节

     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
    ", 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

      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
    ", trie.query(lp[x] - 1, rp[x], y));
    133             else
    134             {
    135                 scanf("%d", &z);
    136                 printf("%d
    ", 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.

  • 相关阅读:
    局部加权回归、欠拟合、过拟合(Locally Weighted Linear Regression、Underfitting、Overfitting)
    损失函数(Loss Function)
    线性回归、梯度下降(Linear Regression、Gradient Descent)
    从BSP模型到Apache Hama
    Apache Hama安装部署
    C#中的面向对象编程
    0<Double.MIN_VALUE
    Java方法的参数传递方式为: 值传递
    数据取对数的意义
    UBuntu安装配置记录
  • 原文地址:https://www.cnblogs.com/Dup4/p/9750468.html
Copyright © 2011-2022 走看看