zoukankan      html  css  js  c++  java
  • ……妈妈我会写维修数列了!

    我是萌萌的传送门

    一道十分恶心的splay模板题,听说有无数神犇花了各种半天/一天才过……

    说说我写这题的历程:

    联赛之前

    第一弹大概在10月份,写的是splay,因为对splay并不熟,把问题想复杂了,吓得没写完就弃坑了。

    第二弹也是10月,这次抄了个fhq Treap模板,结果又W又T,调了一下午+一晚上没出来,弃疗……

    第三弹大概是11月初,重新自己写了个splay,这次好歹能过第一个点,然而还是9个W,各种调不出来,调了几个小时之后怒而第三次弃疗。

    联赛之后

    第四弹,也就是今天,心血来潮想把这道心头大恨切掉,然后就开始写splay,稍微调了一会儿(半个多小时……?)就A了……卧槽怎么维修数列这么简单(装B

    其实splay基本操作并不难,难点主要在附加信息的维护上,表示感觉自己弄出来的几种写法都是等价的,然而只有这个版本能过……

      1 /**************************************************************
      2     Problem: 1500
      3     User: hzoier
      4     Language: C++
      5     Result: Accepted
      6     Time:6048 ms
      7     Memory:41608 kb
      8 ****************************************************************/
      9  
     10 #include<cstdio>
     11 #include<cstring>
     12 #include<algorithm>
     13 #define dir(x) ((int)((x)==(x)->p->ch[1]))
     14 using namespace std;
     15 struct node{
     16     int data,size,sum,prefix,suffix,maxsum;
     17     bool rev,same;
     18     node *ch[2],*p;
     19     node(int d):data(d),size(1),sum(d),prefix(d),suffix(d),maxsum(d),rev(false),same(false){}
     20     void reverse(){
     21         if(data==-1000000)return;
     22         rev^=true;
     23         swap(prefix,suffix);
     24     }
     25     void makesame(int d){
     26         if(data==-1000000)return;
     27         data=d;
     28         sum=d*size;
     29         prefix=suffix=maxsum=max(sum,d);
     30         same=true;
     31     }
     32     void pushdown(){
     33         if(rev){
     34             ch[0]->reverse();
     35             ch[1]->reverse();
     36             swap(ch[0],ch[1]);
     37             rev=false;
     38         }
     39         if(same){
     40             ch[0]->makesame(data);
     41             ch[1]->makesame(data);
     42             same=false;
     43         }
     44     }
     45     void refresh(){
     46         size=ch[0]->size+ch[1]->size+1;
     47         sum=ch[0]->sum+ch[1]->sum+data;
     48         prefix=max(ch[0]->prefix,ch[0]->sum+data+max(ch[1]->prefix,0));
     49         suffix=max(ch[1]->suffix,ch[1]->sum+data+max(ch[0]->suffix,0));
     50         maxsum=max(max(ch[0]->maxsum,ch[1]->maxsum),max(ch[0]->suffix,0)+data+max(ch[1]->prefix,0));
     51     }
     52 }*null=new node(-1000000),*root=null;
     53 void insert(int,int);
     54 void erase(int,int);
     55 void makesame(int,int,int);
     56 void reverse(int,int);
     57 int getsum(int,int);
     58 int maxsum();
     59 node *build(int,int);
     60 void removetree(node*);
     61 node *kth(int);
     62 void splay(node*,node*);
     63 void rot(node*,int);
     64 int n,m,pos,cnt,d,a[5000010];
     65 char c[15];
     66 int main(){
     67     null->ch[0]=null->ch[1]=null->p=null;
     68     null->size=null->sum=0;
     69     scanf("%d%d",&n,&m);
     70     insert(0,n);//dfs(root);
     71     while(m--){
     72         scanf("%s",c);
     73         if(!strcmp(c,"INSERT")){
     74             scanf("%d%d",&pos,&cnt);
     75             insert(pos,cnt);
     76         }
     77         else if(!strcmp(c,"DELETE")){
     78             scanf("%d%d",&pos,&cnt);
     79             erase(pos,cnt);
     80         }
     81         else if(!strcmp(c,"MAKE-SAME")){
     82             scanf("%d%d%d",&pos,&cnt,&d);
     83             makesame(pos,cnt,d);
     84         }
     85         else if(!strcmp(c,"REVERSE")){
     86             scanf("%d%d",&pos,&cnt);
     87             reverse(pos,cnt);
     88         }
     89         else if(!strcmp(c,"GET-SUM")){
     90             scanf("%d%d",&pos,&cnt);
     91             printf("%d
    ",getsum(pos,cnt));
     92         }
     93         else if(!strcmp(c,"MAX-SUM"))printf("%d
    ",maxsum());
     94     }
     95     return 0;
     96 }
     97 node *newnode(int d){
     98     node *x=new node(d);
     99     x->ch[0]=x->ch[1]=x->p=null;
    100     return x;
    101 }
    102 void insert(int pos,int cnt){
    103     for(int i=1;i<=cnt;i++)scanf("%d",&a[i]);
    104     node *x=build(1,cnt);
    105     if(root==null){
    106         root=x;
    107         return;
    108     }
    109     if(!pos){
    110         splay(kth(1),null);
    111         root->ch[0]=x;
    112         x->p=root;
    113         root->refresh();
    114     }
    115     else if(pos==root->size){
    116         splay(kth(root->size),null);
    117         root->ch[1]=x;
    118         x->p=root;
    119         root->refresh();
    120     }
    121     else{
    122         splay(kth(pos),null);
    123         splay(kth(pos+1),root);
    124         root->ch[1]->ch[0]=x;
    125         x->p=root->ch[1];
    126         root->ch[1]->refresh();
    127         root->refresh();
    128     }
    129 }
    130 void erase(int pos,int cnt){
    131     if(cnt==root->size){
    132         removetree(root);
    133         root=null;
    134         return;
    135     }
    136     if(pos==1){
    137         splay(kth(cnt+1),null);
    138         removetree(root->ch[0]);
    139         root->ch[0]=null;
    140         root->refresh();
    141     }
    142     else if(pos+cnt-1==root->size){
    143         splay(kth(pos-1),null);
    144         removetree(root->ch[1]);
    145         root->ch[1]=null;
    146         root->refresh();
    147     }
    148     else{
    149         splay(kth(pos-1),null);
    150         splay(kth(pos+cnt),root);
    151         removetree(root->ch[1]->ch[0]);
    152         root->ch[1]->ch[0]=null;
    153         root->ch[1]->refresh();
    154         root->refresh();
    155     }
    156 }
    157 void makesame(int pos,int cnt,int d){
    158     if(cnt==root->size)root->makesame(d);
    159     else if(pos==1){
    160         splay(kth(cnt+1),null);
    161         root->ch[0]->makesame(d);
    162         root->refresh();
    163     }
    164     else if(pos+cnt-1==root->size){
    165         splay(kth(pos-1),null);
    166         root->ch[1]->makesame(d);
    167         root->refresh();
    168     }
    169     else{
    170         splay(kth(pos-1),null);
    171         splay(kth(pos+cnt),root);
    172         root->ch[1]->ch[0]->makesame(d);
    173         root->ch[1]->refresh();
    174         root->refresh();
    175     }
    176 }
    177 void reverse(int pos,int cnt){
    178     if(cnt==root->size)root->reverse();
    179     else if(pos==1){
    180         splay(kth(cnt+1),null);
    181         root->ch[0]->reverse();
    182         root->refresh();
    183     }
    184     else if(pos+cnt-1==root->size){
    185         splay(kth(pos-1),null);
    186         root->ch[1]->reverse();
    187         root->refresh();
    188     }
    189     else{
    190         splay(kth(pos-1),null);
    191         splay(kth(pos+cnt),root);
    192         root->ch[1]->ch[0]->reverse();
    193         root->ch[1]->refresh();
    194         root->refresh();
    195     }
    196 }
    197 int getsum(int pos,int cnt){
    198     if(!cnt)return 0;
    199     if(cnt==root->size)return root->sum;
    200     else if(pos==1){
    201         splay(kth(cnt+1),null);
    202         return root->ch[0]->sum;
    203     }
    204     else if(pos+cnt-1==root->size){
    205         splay(kth(pos-1),null);
    206         return root->ch[1]->sum;
    207     }
    208     else{
    209         splay(kth(pos-1),null);
    210         splay(kth(pos+cnt),root);
    211         return root->ch[1]->ch[0]->sum;
    212     }
    213 }
    214 int maxsum(){
    215     if(root==null)return 0;
    216     root->pushdown();
    217     return root->maxsum;
    218 }
    219 node *build(int l,int r){
    220     if(l>r)return null;
    221     int mid=(l+r)>>1;
    222     node *x=newnode(a[mid]);
    223     if((x->ch[0]=build(l,mid-1))!=null)x->ch[0]->p=x;
    224     if((x->ch[1]=build(mid+1,r))!=null)x->ch[1]->p=x;
    225     x->refresh();
    226     return x;
    227 }
    228 void removetree(node *x){
    229     if(x==null)return;
    230     removetree(x->ch[0]);
    231     removetree(x->ch[1]);
    232     delete x;
    233 }
    234 node *kth(int k){
    235     node *rt=root;
    236     int d;
    237     while(rt){
    238         rt->pushdown();
    239         if(k==rt->ch[0]->size+1)return rt;
    240         if((d=k>rt->ch[0]->size))k-=rt->ch[0]->size+1;
    241         rt=rt->ch[d];
    242     }
    243     return null;
    244 }
    245 void splay(node *x,node *tar){
    246     while(x->p!=tar){
    247         if(x->p->p==tar){
    248             rot(x->p,dir(x)^1);
    249             break;
    250         }
    251         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    252         else rot(x->p,dir(x)^1);
    253         rot(x->p,dir(x)^1);
    254     }
    255 }
    256 void rot(node *x,int d){
    257     node *y=x->ch[d^1];
    258     x->ch[d^1]=y->ch[d];
    259     if(y->ch[d]!=null)y->ch[d]->p=x;
    260     y->p=x->p;
    261     if(x->p!=null)x->p->ch[dir(x)]=y;
    262     else root=y;
    263     y->ch[d]=x;
    264     x->p=y;
    265     x->refresh();
    266     y->refresh();
    267 }
    View Code

    话说这好像是17年A的第一道题……开门红,不错不错……

  • 相关阅读:
    数字货币资金费策略
    如何利用CCXT交易数字货币合约
    三分钟玩转微软AI量化投资开源库QLib
    商品期货月度效应的统计
    数字货币无风险收益率又双叒叕扩大了!
    Omega System Trading and Development Club内部分享策略Easylanguage源码 (第二期)
    【mac】安装配置 homebrew, Nginx
    【Typescript+Vue】01. easy
    【python】sudo python -m SimpleHTTPServer
    【windows】docker to vmware
  • 原文地址:https://www.cnblogs.com/hzoier/p/6241177.html
Copyright © 2011-2022 走看看