zoukankan      html  css  js  c++  java
  • 军团指挥官(权限题)

    Orz zzd大神太强啦!

    解:首先发现几个性质:如果把区间还原到原序列上的话,可以发现这些区间要么包含,要么相离。不存在相交。

    然后发现如果区间a包含区间b,那么最后剩下来的人,a一定不小于b。又发现最优决策要么是0,要么是在某个极小的区间内。

    然后我们发现这TM不就可以建出一棵树来么?枚举叶节点然后树上倍增找到最多能胜场数,然后取max即可。

    怎么搞出原序列上的区间来呢?我先想到树状数组(????),然后搞了一个小时还不会定位区间,爆0了。

    后来发现splay可以随便水......

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 100010;
      4 
      5 struct Edge {
      6     int nex, v;
      7 }edge[N << 1]; int tp;
      8 
      9 struct Node {
     10     int x, y, l, r, val;
     11     inline bool operator <(const Node &w) const {
     12         if(l != w.l) return l < w.l;
     13         return r > w.r;
     14     }
     15 }node[N];
     16 
     17 int a[N], stk[N], top, root, n, m, K, e[N], pw[N], d[N], fa[N];
     18 int s[N][2], faa[N][20], siz[N], lc[N], rc[N], tot, ST[N][20];
     19 
     20 inline void add(int x, int y) {
     21     tp++;
     22     edge[tp].v = y;
     23     edge[tp].nex = e[x];
     24     e[x] = tp;
     25     return;
     26 }
     27 
     28 inline void pushup(int x) {
     29     siz[x] = siz[s[x][0]] + siz[s[x][1]] + 1;
     30     if(!fa[x]) root = x;
     31     return;
     32 }
     33 
     34 inline void pushdown(int x) {
     35     return;
     36 }
     37 
     38 inline void rotate(int x) {
     39     int y = fa[x];
     40     int z = fa[y];
     41     bool f = (s[y][1] == x);
     42 
     43     fa[x] = z;
     44     if(z) {
     45         s[z][s[z][1] == y] = x;
     46     }
     47     s[y][f] = s[x][!f];
     48     if(s[x][!f]) {
     49         fa[s[x][!f]] = y;
     50     }
     51     s[x][!f] = y;
     52     fa[y] = x;
     53 
     54     pushup(y);
     55     return;
     56 }
     57 
     58 inline void splay(int x, int g = 0) {
     59     int y = x;
     60     stk[top = 1] = y;
     61     while(fa[y]) {
     62         y = fa[y];
     63         stk[++top] = y;
     64     }
     65     while(top) {
     66         pushdown(stk[top]);
     67         top--;
     68     }
     69     y = fa[x];
     70     int z = fa[y];
     71     while(y != g) {
     72         if(z != g) {
     73             (s[y][1] == x) ^ (s[z][1] == y) ?
     74             rotate(x) : rotate(y);
     75         }
     76         rotate(x);
     77         y = fa[x];
     78         z = fa[y];
     79     }
     80     pushup(x);
     81     return;
     82 }
     83 
     84 inline int np(int f, int l, int r) {
     85     int x = ++tot;
     86     fa[x] = f;
     87     lc[x] = l;
     88     rc[x] = r;
     89     siz[x] = 1;
     90     return x;
     91 }
     92 
     93 inline int getPbyR(int k) {
     94     int p = root;
     95     k++;
     96     while(1) {
     97         if(k <= siz[s[p][0]]) {
     98             p = s[p][0];
     99         }
    100         else if(k == siz[s[p][0]] + 1) {
    101             break;
    102         }
    103         else {
    104             k -= siz[s[p][0]] + 1;
    105             p = s[p][1];
    106         }
    107     }
    108     splay(p);
    109     return p;
    110 }
    111 
    112 int build(int f, int l, int r) {
    113     if(l == r) {
    114         return np(f, l, r);
    115     }
    116     int mid = (l + r) >> 1;
    117     int x = np(f, mid, mid);
    118     if(l < mid) s[x][0] = build(x, l, mid - 1);
    119     if(mid < r) s[x][1] = build(x, mid + 1, r);
    120     pushup(x);
    121     return x;
    122 }
    123 
    124 inline int getL(int p = root) {
    125     pushdown(p);
    126     while(s[p][0]) {
    127         p = s[p][0];
    128         pushdown(p);
    129     }
    130     return p;
    131 }
    132 
    133 inline int getR(int p = root) {
    134     pushdown(p);
    135     while(s[p][1]) {
    136         p = s[p][1];
    137         pushdown(p);
    138     }
    139     return p;
    140 }
    141 
    142 inline void merge(int x, int l, int r) {
    143     lc[x] = l;
    144     rc[x] = r;
    145     siz[x] = 1;
    146     s[x][0] = s[x][1] = 0;
    147     return;
    148 }
    149 
    150 inline void prework() {
    151     for(int i = 2; i <= n; i++) {
    152         pw[i] = pw[i >> 1] + 1;
    153     }
    154     for(int i = 1; i < n; i++) ST[i][0] = a[i];
    155     for(int j = 1; j <= pw[n]; j++) {
    156         for(int i = 1; i + (1 << j) - 1 <= n; i++) {
    157             ST[i][j] = std::max(ST[i][j - 1], ST[i + (1 << (j - 1))][j - 1]);
    158         }
    159     }
    160     return;
    161 }
    162 
    163 inline void prework2() {
    164     for(int j = 1; j <= pw[m]; j++) {
    165         for(int i = 1; i <= m; i++) {
    166             faa[i][j] = faa[faa[i][j - 1]][j - 1];
    167         }
    168     }
    169     return;
    170 }
    171 
    172 inline int getPos(int x) {
    173     int t = pw[m];
    174     while(t >= 0) {
    175         if(faa[x][t] && node[faa[x][t]].val <= K) {
    176             x = faa[x][t];
    177         }
    178         t--;
    179     }
    180     return x;
    181 }
    182 
    183 inline int getMax(int x, int y) {
    184     int t = pw[y - x + 1];
    185     return std::max(ST[x][t], ST[y - (1 << t) + 1][t]);
    186 }
    187 /*
    188 5 3 3
    189 1 0 2 4
    190 1 3
    191 0 1
    192 0 1
    193 */
    194 int main() {
    195 
    196     scanf("%d%d%d", &n, &m, &K);
    197     for(int i = 1; i < n; i++) {
    198         scanf("%d", &a[i]);
    199     }
    200     for(int i = 1; i <= m; i++) {
    201         scanf("%d%d", &node[i].x, &node[i].y);
    202         node[i].x++;
    203         node[i].y++;
    204     }
    205     /// input OVER
    206 
    207     prework();
    208     root = build(0, 0, n + 1);
    209 
    210     for(int i = 1; i <= m; i++) {
    211         int L = getPbyR(node[i].x - 1);
    212         int R = getPbyR(node[i].y + 1);
    213         splay(L, R);
    214         int l = getL(s[L][1]), r = getR(s[L][1]);
    215         node[i].l = lc[l];
    216         node[i].r = rc[r];
    217         node[i].val = getMax(node[i].l, node[i].r - 1);
    218         merge(s[L][1], node[i].l, node[i].r);
    219         pushup(L);
    220         pushup(R);
    221     }
    222 
    223     std::sort(node + 1, node + m + 1);
    224     top = 0;
    225     for(int i = 1; i <= m; i++) {
    226         while(top && node[i].l > node[stk[top]].r) {
    227             top--;
    228         }
    229         if(top) {
    230             add(stk[top], i);
    231             faa[i][0] = stk[top];
    232         }
    233         stk[++top] = i;
    234     }
    235 
    236     prework2();
    237     for(int i = 1; i <= m; i++) {
    238         d[i] = d[faa[i][0]] + 1;
    239     }
    240 
    241     int ans = 0, pos = 1;
    242     for(int x = 1; x <= m; x++) {
    243         if(e[x] || node[x].val > K) continue;
    244         int t = getPos(x);
    245         t = d[x] - d[t] + 1;
    246         if(t > ans) {
    247             ans = t;
    248             pos = node[x].l;
    249         }
    250         else if(t == ans) {
    251             pos = std::min(pos, node[x].l);
    252         }
    253     }
    254 
    255     printf("%d
    ", pos - 1);
    256     return 0;
    257 }
    AC代码
  • 相关阅读:
    2018-2019-2 实验三 敏捷开发与XP实践
    计算机网络课外实验一级 20175319江野
    2018-2019-2 《Java程序设计》第9周学习总结
    MyCP(课下作业,必做)
    [NOIP2012] 疫情控制
    [SPOJ2021] Moving Pebbles
    谁能赢呢?
    [HEOI2014] 人人尽说江南好
    [笔记] 巴什博弈
    [SCOI2008] 着色方案
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10588346.html
Copyright © 2011-2022 走看看