• POJ 3580 SuperMemo 题解


    题目大意:维护一个序列,支持6种操作:

    1、ADD x y D 从第x个数到第y个数都增加D

    2、REVERSE x y 翻转第x个数到第y个数

    3、REVOLVE x y T 从x到y,向右循环移动T次

    4、INSERT x P 插入P到第x个数后面

    5、DELETE x 删除第x个数

    6、MIN x y 查询第x个数到第y个数之间最小值

    ADD和REVERSE打标记然后及时下传就可以。。REVOLVE的T可能为负还可能很大,要注意取模。REVOLVE可以通过3个REVERSE操作完成,也可以通过分离和合并完成,只不过代码稍微长一点。INSERT可以将x提到根,x+1提到root下面,此时根节点的右儿子的左儿子为空,新建一个结点,维护信息。也可以将x提到根,新建结点t,使t->ch[1]=root->ch[1],再使root->ch[1]=t。DELETE可以将x-1提到根,x+1提到root下面,删除root->ch[1]->ch[0],维护信息。 

    代码长,细节多。。容易出错。这题好像RE会显示TLE。。不知道是什么问题

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 const int INF=~0U>>1;
      5 const int MAXN=100000+10;
      6 int n,m;
      7 int a[MAXN];
      8 struct Node{
      9     int s,v,add,mn;
     10     bool rev;
     11     Node* p,*ch[2];
     12     Node() {s=0;add=0;v=mn=INF;}
     13     inline bool d() {return p->ch[1]==this;}
     14     inline void setc(Node* o,int d)
     15     {
     16         ch[d]=o;
     17         o->p=this;
     18     }
     19     inline void addIt(int x)
     20     {
     21         add+=x;
     22         mn+=x;
     23         v+=x;
     24     }
     25     inline void revIt()
     26     {
     27         rev^=1;
     28     }
     29     inline void maintain()
     30     {
     31         s=ch[0]->s+ch[1]->s+1;
     32         mn=std::min(v,std::min(ch[0]->mn,ch[1]->mn));
     33     }
     34     inline void pushdown();
     35 }Tnull,*null=&Tnull;
     36 Node mem[MAXN<<1],*C=mem;
     37 inline void Node::pushdown()
     38 {
     39     if(add)
     40     {
     41         if(ch[0]!=null) ch[0]->addIt(add);
     42         if(ch[1]!=null) ch[1]->addIt(add);
     43         add=0;
     44     }
     45     if(rev)
     46     {
     47         std::swap(ch[0],ch[1]);
     48         if(ch[0]!=null) ch[0]->revIt();
     49         if(ch[1]!=null) ch[1]->revIt();
     50         rev=0;
     51     }
     52 }
     53 inline Node* newnode(int v)
     54 {
     55     C->ch[0]=C->ch[1]=null;
     56     C->s=1;
     57     C->v=C->mn=v;
     58     C->add=C->rev=0;
     59     return C++;
     60 }
     61 Node* build(int l,int r) //[l,r)
     62 {
     63     if(l>=r) return null;
     64     int m=l+(r-l)/2;
     65     Node* t=newnode(a[m]);
     66     t->setc(build(l,m),0);
     67     t->setc(build(m+1,r),1);
     68     t->maintain();
     69     return t;
     70 }
     71 Node* root;
     72 inline void rot(Node* t)
     73 {
     74     Node* p=t->p;
     75     p->pushdown();t->pushdown();
     76     int d=t->d();
     77     p->p->setc(t,p->d());
     78     p->setc(t->ch[d^1],d);
     79     t->setc(p,d^1);
     80     p->maintain();
     81     if(p==root)
     82         root=t;
     83 }
     84 void splay(Node* t,Node* f=null)
     85 {
     86     while(t->p!=f)
     87     {
     88         if(t->p->p==f) rot(t);
     89         else t->d()==t->p->d()?(rot(t->p),rot(t)):(rot(t),rot(t));
     90     }
     91     t->maintain();
     92 }
     93 Node* select(int k)
     94 {
     95     for(Node* t=root;;)
     96     {
     97         t->pushdown();
     98         int s=t->ch[0]->s;
     99         if(k==s) return t;
    100         if(k>s) k-=s+1,t=t->ch[1];
    101         else t=t->ch[0];
    102     }
    103 }
    104 inline Node*& get(int l,int r) //[l,r)
    105 {
    106     Node* L=select(l-1);
    107     Node* R=select(r);
    108     splay(L);
    109     splay(R,root);
    110     return R->ch[0];
    111 }
    112 inline void Reverse(int l,int r)
    113 {
    114     Node*& t=get(l,r+1);
    115     t->revIt();
    116 }
    117 inline void Insert(int x,int P)
    118 {
    119     splay(select(x));
    120     Node* t=newnode(P);
    121     t->setc(root->ch[1],1);
    122     root->setc(t,1);
    123     t->maintain();
    124     root->maintain();
    125 }
    126 inline void Add(int x,int y,int D)
    127 {
    128     Node*& t=get(x,y+1);
    129     t->addIt(D);
    130 }
    131 inline void Revolve(int x,int y,int T)
    132 {
    133     int l=y+1-x;
    134     T=(T%l+l)%l;
    135     if(T==0) return;
    136     Reverse(x,y);
    137     Reverse(x,x+T-1);
    138     Reverse(x+T,y);
    139 }
    140 inline int Min(int x,int y)
    141 {
    142     Node* &t=get(x,y+1);
    143     return  t->mn;
    144 }
    145 inline void Delete(int x)
    146 {
    147     splay(select(x-1));
    148     splay(select(x+1),root);
    149     root->ch[1]->ch[0]=null;
    150     root->ch[1]->maintain();
    151     root->maintain();
    152 }
    153 int main()
    154 {
    155 //    freopen("1.in","r",stdin);
    156     scanf("%d",&n);
    157     for(int i=1;i<=n;++i)
    158         scanf("%d",a+i);
    159     a[0]=a[n+1]=INF;
    160     root=build(0,n+2);
    161     root->p=null;
    162     scanf("%d",&m);
    163     while(m--)
    164     {
    165         int x,y,k;
    166         char s[20];
    167         scanf("%s",s);
    168         switch(s[0])
    169         {
    170             case 'A':scanf("%d%d%d",&x,&y,&k);
    171                      Add(x,y,k);
    172                      break;
    173             case 'I':scanf("%d%d",&x,&k);
    174                      Insert(x,k);
    175                      break;
    176             case 'D':scanf("%d",&x);
    177                      Delete(x);
    178                      break;
    179             case 'M':scanf("%d%d",&x,&y);
    180                      printf("%d\n",Min(x,y));
    181                      break;
    182             case 'R':if(s[3]=='E')
    183                      {
    184                          scanf("%d%d",&x,&y);
    185                         Reverse(x,y);
    186                      }
    187                      else
    188                      {
    189                          scanf("%d%d%d",&x,&y,&k);
    190                         Revolve(x,y,k);
    191                      }
    192         }
    193     }
    194     return 0;
    195 }
    View Code
  • 相关阅读:
    nop调试-区域路由问题
    nop4.3 用户权限管理
    nop4.3 admin中添加新菜单
    nop 中创建任务(Task)
    SignalR 的应用
    mvc和ef如何连接
    .net中微信、支付宝回调
    C# 中使用Aspose.Words下载文档
    添加 Azure Active Directory 服务,调用方法
    Net Core 5.0 部署IIS错误-500.31-Failed to load ASP.NET Core runtime
  • 原文地址:https://www.cnblogs.com/lowsfish/p/4328596.html
Copyright © 2020-2023  润新知