• HDU5773-The All-purpose Zero-多校#41010-最长上升子序列问题


    只想到了朴素的n^2做法,然后发现可以用splay维护。于是调了几个小时的splay。。。

    splay的元素是从第二个开始的!第一个是之前插入的头节点!

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 
      7 #define Key_value ch[ch[root][1] ][0]
      8 
      9 const int maxn = 5e5+10;
     10 const int INF = 0x3f3f3f3f;
     11 
     12 int pre[maxn],ch[maxn][2],key[maxn],sz[maxn];
     13 int root,tot1;
     14 int rev[maxn],ma[maxn],add[maxn];
     15 int s[maxn],tot2;
     16 int a[maxn];
     17 //int n,q;
     18 
     19 void Treavel(int x)
     20 {
     21     if(x)
     22     {
     23         Treavel(ch[x][0]);
     24         printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d size= %2d ma=%2d add=%2d
    ",x,ch[x][0],ch[x][1],pre[x],key[x],sz[x],ma[x],add[x]);
     25         Treavel(ch[x][1]);
     26     }
     27 }
     28 void debug()
     29 {
     30     printf("root:%d
    ",root);
     31     Treavel(root);
     32 }
     33 //
     34 
     35 void NewNode(int &r,int father,int k)
     36 {
     37     if(tot2) r = s[tot2--];
     38     else r = ++tot1;
     39     pre[r] = father;
     40     ch[r][0] = ch[r][1] = 0;
     41     key[r] = k;
     42     ma[r] = k;
     43     rev[r] = add[r] = 0;
     44     sz[r] = 1;
     45 }
     46 
     47 void Update_add(int r,int c)
     48 {
     49     if(!r) return ;
     50     key[r] += c;
     51     ma[r] += c;
     52     add[r] += c;
     53 }
     54 
     55 void Update_rev(int r)
     56 {
     57     if(!r) return ;
     58     swap(ch[r][0],ch[r][1]);
     59     rev[r] ^= 1;
     60 }
     61 
     62 void push_up(int r)
     63 {
     64     int lson = ch[r][0],rson = ch[r][1];
     65     sz[r] = sz[lson] + sz[rson] + 1;
     66     //ma[r] = max(max(ma[lson],ma[rson]),key[r]);
     67     ma[r] = max(max(ma[lson],ma[rson]),key[r]);
     68 }
     69 void update_same(int r,int c)
     70 {
     71     if(!r) return ;
     72     int lson = ch[r][0],rson = ch[r][1];
     73     key[r] = c;
     74     //ma[r] = max(max(ma[lson],ma[rson]),c);
     75     ma[r] = c;
     76 }
     77 void push_down(int r)
     78 {
     79     if(rev[r])
     80     {
     81         Update_rev(ch[r][0]);
     82         Update_rev(ch[r][1]);
     83         rev[r] = 0;
     84     }
     85     if(add[r])
     86     {
     87         Update_add(ch[r][0],add[r]);
     88         Update_add(ch[r][1],add[r]);
     89         add[r] = 0;
     90     }
     91 }
     92 
     93 void Build(int &x,int l,int r,int father)
     94 {
     95     if(l>r) return ;
     96     int mid = (l+r)>>1;
     97     NewNode(x,father,a[mid]);
     98     Build(ch[x][0],l,mid-1,x);
     99     Build(ch[x][1],mid+1,r,x);
    100     push_up(x);
    101 }
    102 
    103 void Init(int x)
    104 {
    105     root = tot1 = tot2 = 0;
    106     ch[root][0] = ch[root][1] = sz[root] = pre[root] = 0;
    107     rev[root] = key[root] = 0;
    108     ma[root] = 0;
    109     NewNode(root,0,-1);
    110     NewNode(ch[root][1],root,-1);
    111     //for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    112     a[1] = x;
    113     //n = 1;
    114     Build(Key_value,1,1,ch[root][1]);
    115     push_up(ch[root][1]);
    116     push_up(root);
    117 }
    118 
    119 void Rotate(int x,int kind)
    120 {
    121     int y = pre[x];
    122     push_down(y);
    123     push_down(x);
    124     ch[y][!kind] = ch[x][kind];
    125     pre[ch[x][kind] ] = y;
    126     if(pre[y])
    127         ch[pre[y] ][ch[pre[y]][1]==y ] = x;
    128     pre[x] = pre[y];
    129     ch[x][kind] = y;
    130     pre[y] = x;
    131     push_up(y);
    132 }
    133 void Splay(int r,int goal)
    134 {
    135     push_down(r);
    136     while(pre[r] != goal)
    137     {
    138         if(pre[pre[r] ] == goal)
    139         {
    140             push_down(pre[r]);
    141             push_down(r);
    142             Rotate(r,ch[pre[r]][0] == r);
    143         }
    144         else
    145         {
    146             push_down(pre[pre[r] ]);
    147             push_down(pre[r]);
    148             push_down(r);
    149             int y = pre[r];
    150             int kind = ch[pre[y] ][0] == y;
    151             if(ch[y][kind] == r)
    152             {
    153                 Rotate(r,!kind);
    154                 Rotate(r,kind);
    155             }
    156             else
    157             {
    158                 Rotate(y,kind);
    159                 Rotate(r,kind);
    160             }
    161         }
    162         push_up(r);
    163         if(goal == 0) root = r;
    164     }
    165 }
    166 
    167 int Get_kth(int r,int k)
    168 {
    169     push_down(r);
    170     int t = sz[ch[r][0] ] + 1;
    171     if(t == k) return r;
    172     if(t > k) return Get_kth(ch[r][0],k);
    173     else return Get_kth(ch[r][1],k-t);
    174 }
    175 
    176 void Insert(int pos,int x)
    177 {
    178     //for(int i=0;i<tot;i++) scanf("%d",&a[i]);
    179     int tot = 1;
    180     a[0] = x;
    181     Splay(Get_kth(root,pos) , 0);
    182     Splay(Get_kth(root,pos+1) , root);
    183     Build(Key_value,0,tot-1,ch[root][1]);
    184     push_up(ch[root][1]);
    185     push_up(root);
    186 }
    187 void erase(int r)
    188 {
    189     if(!r) return ;
    190     s[++tot2] = r;
    191     erase(ch[r][0]);
    192     erase(ch[r][1]);
    193 }
    194 void Delete(int pos,int tot)
    195 {
    196     Splay(Get_kth(root,pos) ,0);
    197     Splay(Get_kth(root,pos+tot+1) , root);
    198     erase(Key_value);
    199     pre[Key_value] = 0;
    200     Key_value = 0;
    201     push_up(ch[root][1]);
    202     push_up(root);
    203 }
    204 
    205 void Reverse(int pos,int tot)
    206 {
    207     Splay(Get_kth(root,pos) , 0);
    208     Splay(Get_kth(root,pos+tot+1), root);
    209     Update_rev(Key_value);
    210 }
    211 
    212 void Add(int pos,int tot,int c)
    213 {
    214     Splay(Get_kth(root,pos) , 0);
    215     Splay(Get_kth(root,pos+tot+1) , root);
    216     Update_add(Key_value,c);
    217     push_up(ch[root][1]);
    218     push_up(root);
    219 }
    220 void Make_same(int pos,int tot,int c)
    221 {
    222     Splay(Get_kth(root,pos) , 0);
    223     Splay(Get_kth(root,pos+tot+1) , root);
    224     //printf("tihuan
    ");
    225     //debug();
    226     update_same(Key_value,c);
    227     push_up(ch[root][1]);
    228     push_up(root);
    229 }
    230 int Get_max(int pos,int tot)
    231 {
    232     Splay(Get_kth(root,pos) , 0);
    233     Splay(Get_kth(root,pos+tot+1) , root);
    234     push_down(root);
    235     push_down(ch[root][1]);
    236     return ma[Key_value];
    237 }
    238 int Get_final_ans(int pos,int tot,int x)
    239 {
    240     int low = pos+1,high = pos+tot-1;
    241     int mid;
    242     while(low <= high)
    243     {
    244         mid = (low+high)>>1;
    245         int b = key[Get_kth(root,mid)];
    246         //printf("mid:%d k:%d
    ",mid,b);
    247         if(x >= b) low = mid+1;
    248         else high = mid -1;
    249     }
    250     //printf("l:%d h:%d m:%d
    ",low,high,mid);
    251     return (low+high)>>1;
    252 }
    253 
    254 void Revolve(int l,int r,int t)
    255 {
    256     if(!t) return ;
    257     int c = r - t;
    258     Splay(Get_kth(root,l) , 0);
    259     Splay(Get_kth(root,c+2),root);
    260     int tmp = Key_value;
    261     Key_value = 0;
    262     push_up(ch[root][1]);
    263     push_up(root);
    264     Splay(Get_kth(root,r-c+l) , 0);
    265     Splay(Get_kth(root,r-c+l+1) , root);
    266     Key_value = tmp;
    267     pre[Key_value] = ch[root][1];
    268     push_up(ch[root][1]);
    269     push_up(root);
    270 }
    271 
    272 int save[maxn];
    273 int T,N;
    274 int LL,RR;
    275 int DP(int l,int n)
    276 {
    277     if(n==0) return 0;
    278     int i,len=1,pos;
    279     Init(save[l]);
    280     //debug();
    281     //printf("---
    ");
    282     for(int i=l+1;i<=n;i++)
    283     {
    284         //printf("save:%d len:%d max:%d
    ",save[i],len,Get_max(1,len));
    285         if(save[i] == 0)
    286         {
    287             Add(1,len,1);
    288             Insert(1,0);
    289             len++;
    290         }
    291         else if(save[i] > Get_max(1,len))
    292         {
    293             //printf("max:%d
    ",Get_max(1,len));
    294             Insert(len+1,save[i]);
    295             len++;
    296         }
    297         else{
    298             pos = Get_final_ans(1,len,save[i]);
    299             //printf("pos:%d
    ",pos);
    300             //Add(pos,1,save[i]-key[Get_kth(root,pos)]);
    301             Make_same(pos,1,save[i]);
    302         }
    303 
    304         //debug();
    305         //printf("---
    ");
    306     }
    307     return len;
    308 }
    309 bool flag = false;
    310 void deal()
    311 {
    312     int i = 1;
    313     while( save[i]==0 && i <= N) i++;
    314     LL = i;
    315     i = N;
    316     if(LL>=N ) {flag = true;return;}
    317     while(save[i] == 0 && i >= 0) i--;
    318     RR = i;
    319 }
    320 int main()
    321 {
    322     //freopen("input","r",stdin);
    323     //freopen("splay.out","w",stdout);
    324     scanf("%d",&T);
    325     for(int cas=1;cas<=T;cas++)
    326     {
    327         scanf("%d",&N);
    328         for(int i=1;i<=N;i++)
    329         {
    330             scanf("%d",&save[i]);
    331         }
    332         flag = false;
    333         deal();
    334         if(flag){
    335             printf("Case #%d: %d
    ",cas,N);
    336             continue;
    337         }
    338         //printf("LL:%d RR:%d
    ",LL,RR);
    339         int ans = DP(LL,RR);
    340         printf("Case #%d: %d
    ",cas,ans+LL-1+(N-RR));
    341     }
    342 }
    343 /*
    344 int m;
    345 int main()
    346 {
    347     while(~scanf("%d ",&n))
    348     {
    349         Init();
    350         //debug();
    351         scanf("%d ",&m);
    352         char op[10];
    353         for(int i=0;i<m;i++)
    354         {
    355             scanf(" %s",op);
    356             //printf("i:%d op:%s
    ",i,op);
    357             int x,y,c,t;
    358             if(op[0] == 'A')            //add
    359             {
    360                 scanf("%d%d%d",&x,&y,&c);
    361                 Add(x,y-x+1,c);
    362             }
    363             else if(op[0] == 'I')       //insert
    364             {
    365                 scanf("%d",&x);
    366                 Insert(x,1);
    367             }
    368             else if(op[0] == 'D')       //delete
    369             {
    370                 scanf("%d",&x);
    371                 Delete(x,1);
    372             }
    373             else if(op[0] == 'M')       //min
    374             {
    375                 scanf("%d%d",&x,&y);
    376                 printf("%d
    ",Get_min(x,y-x+1));
    377             }
    378             else if(op[0] == 'R' && op[3] == 'E')//reverse
    379             {
    380                 scanf("%d%d",&x,&y);
    381                 Reverse(x,y-x+1);
    382             }
    383             else                        //revolve
    384             {
    385                 scanf("%d%d%d",&x,&y,&t);
    386                 t = (t%(y-x+1)+(y-x+1))%(y-x+1);
    387                 Revolve(x,y,t);
    388             }
    389             //debug();
    390         }
    391     }
    392 }
    393 */
  • 相关阅读:
    py基础之模块与包
    py装饰器,生成器,迭代器
    py函数式编程
    py基础之列表生成式
    算法基础之递归算法
    Py基础之函数
    py基础之无序列表
    py基础之数据类型及基本语法
    jsp报错问题汇总
    mysql问题汇总
  • 原文地址:https://www.cnblogs.com/helica/p/5720800.html
Copyright © 2020-2023  润新知