zoukankan      html  css  js  c++  java
  • BZOJ1493 [NOI2007]项链工厂

    未完待续。。。

    终于改对了 热泪盈眶.jpg

    错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 500005
      4 char s[10];
      5 int n,m;
      6 int root,fa[N],sz[N],ch[N][2],lc[N],rc[N],num[N],c[N],rev[N],tag[N];
      7 void pushup(int x){
      8   int l=ch[x][0],r=ch[x][1];
      9   sz[x]=sz[l]+sz[r]+1;
     10   num[x]=num[l]+num[r]+1;
     11   lc[x]=rc[x]=c[x];
     12   if(l)num[x]-=rc[l]==c[x],lc[x]=lc[l];
     13   if(r)num[x]-=lc[r]==c[x],rc[x]=rc[r];
     14 }
     15 void pushdown(int x){
     16   if(!x)return;
     17   int l=ch[x][0],r=ch[x][1];
     18   if(tag[x]){
     19     tag[x]=0;  
     20     if(l){  
     21       num[l]=1;tag[l]=1;  
     22       lc[l]=rc[l]=c[l]=c[x];  
     23     }  
     24     if(r){  
     25       num[r]=1;tag[r]=1;  
     26       lc[r]=rc[r]=c[r]=c[x];  
     27     }  
     28   }
     29   if(rev[x]){  
     30     rev[x]^=1;rev[l]^=1;rev[r]^=1;  
     31     if(l){  
     32       swap(lc[l],rc[l]);  
     33       swap(ch[l][0],ch[l][1]);  
     34     }  
     35     if(r){  
     36       swap(lc[r],rc[r]);  
     37       swap(ch[r][0],ch[r][1]);  
     38     }  
     39   }  
     40 }
     41 void rotate(int x){
     42   int y=fa[x],z=fa[y],k=ch[y][1]==x;
     43   fa[ch[y][k]=ch[x][!k]]=y;
     44   fa[ch[x][!k]=y]=x;
     45   fa[x]=z;
     46   if(z)ch[z][ch[z][1]==y]=x;else root=x;
     47   pushup(y);
     48 }
     49 void splay(int x,int f){
     50   pushdown(x);
     51   while(fa[x]!=f){
     52     int y=fa[x],z=fa[y];
     53     pushdown(z);pushdown(y);pushdown(x);
     54     if(z==f)rotate(x);
     55     else{
     56       if((ch[z][1]==y)==(ch[y][1]==x))rotate(y);
     57       else rotate(x);
     58       rotate(x);
     59     }
     60   }
     61   pushup(x);
     62 }
     63 int select(int k,int f){
     64   int x=root;pushdown(x);
     65   while(sz[ch[x][0]]!=k-1){
     66     if(sz[ch[x][0]]>=k)x=ch[x][0];
     67     else k-=sz[ch[x][0]]+1,x=ch[x][1];
     68     pushdown(x);
     69   }
     70   splay(x,f);
     71   return x;
     72 }
     73 void build(int l,int r,int f){
     74   int mid=l+r>>1;
     75   fa[mid]=f;if(mid<f)ch[f][0]=mid;else ch[f][1]=mid;
     76   if(l==r){sz[mid]=1;lc[mid]=rc[mid]=c[mid];num[mid]=1;return;}
     77   if(l<mid)build(l,mid-1,mid);
     78   if(r>mid)build(mid+1,r,mid);
     79   pushup(mid);
     80 }
     81 void change(int k){
     82   int x=select(n-k-1,0),y=select(n,root);
     83   int z=ch[y][0];fa[z]=0;ch[y][0]=0;
     84   pushup(y);pushup(x);
     85   x=select(1,0);y=select(2,root);
     86   ch[y][0]=z;fa[z]=y;
     87   pushup(y);pushup(x);
     88 }
     89 void Flip(){
     90   int x=select(2,0),y=select(n,root);
     91   int z=ch[y][0];
     92   if(tag[z])return;
     93   rev[z]^=1;swap(ch[z][0],ch[z][1]);swap(lc[z],rc[z]);
     94   pushup(y);pushup(x);
     95 }
     96 void Swap(int x,int y){
     97   x=select(x+1,0);
     98   int cx=c[x];
     99   y=select(y+1,0);
    100   int cy=c[y];
    101   c[y]=cx;pushup(y);
    102   splay(x,0);
    103   c[x]=cy;pushup(x);
    104 }
    105 void Paint(int x,int y,int cc){
    106   if(x<=y){
    107     x=select(x,0);
    108     y=select(y+2,root);
    109     int z=ch[y][0];
    110     tag[z]=1;
    111     c[z]=lc[z]=rc[z]=cc;num[z]=1;
    112     splay(z,0);
    113   }
    114   else{
    115     change(n-1-x);
    116     Paint(1,n-1-x+y,cc);
    117     change(x-1);
    118   }
    119 }
    120 int CountSeg(int x,int y){
    121   if(x<=y){
    122     x=select(x,0);y=select(y+2,root);
    123     return num[ch[y][0]];
    124   }
    125   else{
    126     change(n-1-x);
    127     int ans=CountSeg(1,n-1-x+y);
    128     change(x-1);
    129     return ans;
    130   }
    131 }
    132 int Count(){
    133   int ans=num[root]-2;
    134   int x=select(1,0),y=select(n,root);
    135   int z=ch[y][0];
    136   ans-=lc[z]==rc[z];
    137   return max(ans,1);
    138 }
    139 int main(){
    140   scanf("%d%d",&n,&m);
    141   for(int i=2;i<=n+1;i++)scanf("%d",&c[i]);
    142   n+=2;build(1,n,0);root=(1+n)>>1;
    143   scanf("%d",&m);
    144   int x,y,z;
    145   while(m--){
    146       scanf("%s",s);
    147       if(s[0]=='R'){
    148         scanf("%d",&x);change(x);
    149     }
    150       else if(s[0]=='F')Flip();
    151       else if(s[0]=='S'){
    152         scanf("%d%d",&x,&y);Swap(x,y);
    153     }
    154       else if(s[0]=='P'){
    155         scanf("%d%d%d",&x,&y,&z);
    156         Paint(x,y,z);
    157       }
    158       else if(s[1]=='S'){
    159         scanf("%d%d",&x,&y);
    160       printf("%d
    ",CountSeg(x,y));    
    161       }
    162       else printf("%d
    ",Count());
    163   }
    164   return 0;
    165 }
    View Code

    1493: [NOI2007]项链工厂

    Time Limit: 30 Sec  Memory Limit: 64 MB
    Submit: 1320  Solved: 576
    [Submit][Status][Discuss]

    Description

    T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。
    最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。该项链自助生产系
    统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的
    项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能
    帮助T公司编写一个软件模拟系统吗?一条项链包含 N 个珠子,每个珠子的颜色是 1,2,…,c 中的一种。项链
    被固定在一个平板上,平板的某个位置被标记位置 1 ,按顺时针方向其他位置被记为 2,3,…,N。
    你将要编写的软件系统应支持如下命令:

    Input

    输入文件第一行包含两个整数 N,c ,分别表示项链包含的珠子数目以及颜色数目。
    第二行包含 N 个整数,x1,x2,…,xn ,表示从位置 1 到位置 N 的珠子的颜色,1≤xi≤c 。
    第三行包含一个整数 Q ,表示命令数目。接下来的 Q 行每行一条命令,如上文所述。N≤500000 ,Q≤500000,c≤1000 
     

    Output

    对于每一个 C 和 CS 命令,应输出一个整数代表相应的答案。

    Sample Input

    5 3
    1 2 3 2 1
    4
    C
    R 2
    P 5 5 2
    CS 4 1

    Sample Output

    4
    1

    HINT

    注意旋转命令旋转“珠子”但不改变“位置”的编号,而反转命令始终以位置 1 为对称轴。例如当 N=10 时,项

    链上的位置编号如图1:



    但注意此时项链上的位置编号仍然如图1所示,于是翻转的对称轴不变。因而再执行一次“F”命令时,项链的颜色

    如图4所示。

    2. 关于CountSegment命令CS命令表示查询一个“线段”中有多少个“部分”。尤其注意当查询的长度

    等于 N 时,我们仍然将查询部分作为“线段”理解。例如在图4所示的情况中,执行“CS 1 10”命令,查询从位

    置 1 开始到位置 10 结束的这个长度为 10 的线段中有多少个“部分”,于是得到返回值 3 。与之形成对照的是

    ,若执行“C”命令,返回值则为 2
  • 相关阅读:
    cart树剪枝
    LSA、LDA
    paddle中新增layer
    https://www.i5seo.com/
    打印机彩色打印设置(将彩色打印为黑色)
    办公文档的标准格式
    电脑常用的5个按键
    Win7各个版本之间的区别
    win7保护眼睛的颜色设置方法(85,125,205)
    详细教您台式电脑如何组装
  • 原文地址:https://www.cnblogs.com/wjyi/p/5616353.html
Copyright © 2011-2022 走看看