• 数据结构(Splay平衡树): [NOI2007] 项链工厂


     [NOI2007] 项链工厂

    ★★★   输入文件:necklace.in   输出文件:necklace.out   简单对比
    时间限制:4 s   内存限制:512 MB

    【问题描述】

    T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。

    该项链自助生产系统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能帮助T公司编写一个软件模拟系统吗?

    一条项链包含N个珠子,每个珠子的颜色是1, 2, …, c中的一种。项链被固定在一个平板上,平板的某个位置被标记位置1,按顺时针方向其他位置被记为2,3,…,N。

    Image:Necklace2007.jpg

    你将要编写的软件系统应支持如下命令:

    命令 参数限制 内容
    R k 0 意为Rotate k。将项链在平板上顺时针旋转k个位置, 即原来处于位置1的珠子将转至位置k+1,处于位置2的珠子将转至位置k+2,依次类推。
    F   意为Flip。将平板沿着给定的对称轴翻转,原来处于位置1的珠子不动,位置2上的珠子与位置N上的珠子互换,位置3上的珠子与位置N-1上的珠子互换,依次类推。
    S i j 1≤i , j≤N 意为Swap i , j。将位置i上的珠子与位置j上的珠子互换。
    P i j x 1≤i , j≤N, x≤c 意为Paint i , j , x。将位置i沿顺时针方向到位置j的一段染为颜色x。
    C   意为Count。查询当前的项链由多少个“部分”组成,我们称项链中颜色相同的一段为一个“部分”
    CS i j 1≤i , j≤N 意为CountSegment i , j。查询从位置i沿顺时针方向到位置j的一段中有多少个部分组成。

    【输入文件】

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

    【输出文件】

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

    【输入样例】

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

    【输出样例】

    4
    1
    

    【评分方法】

    本题没有部分分,你的程序的输出只有和标准答案完全一致才能获得满分, 否则不得分。

    【数据规模和约定】

    • 对于60%的数据,N ≤1 000,Q ≤1 000;
    • 对于100%的数据,N ≤500 000,Q ≤500 000,c ≤1 000。

      改了一上午终于AC!

      发现自己一直看错题了,Flip指令要以1为中轴,所以1不参与Flip!!!

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 const int maxn=500010;
      6 int ch[maxn][2],fa[maxn],sz[maxn],flip[maxn],mark[maxn];
      7 int key[maxn],tot[maxn],L[maxn],R[maxn],rt;
      8 int n,Q,l,r,d,c;
      9 char op[10];
     10 void Push_up(int x){
     11     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
     12     L[x]=ch[x][0]?L[ch[x][0]]:key[x];
     13     R[x]=ch[x][1]?R[ch[x][1]]:key[x];
     14     tot[x]=tot[ch[x][0]]+tot[ch[x][1]]+1;
     15     if(ch[x][0]&&R[ch[x][0]]==key[x])tot[x]-=1;
     16     if(ch[x][1]&&key[x]==L[ch[x][1]])tot[x]-=1;
     17 }
     18  
     19 void Flip(int x){
     20     if(!x)return;
     21     swap(ch[x][0],ch[x][1]);
     22     swap(L[x],R[x]);
     23     flip[x]^=1;
     24 }
     25  
     26 void Mark(int x,int d){
     27     if(!x)return;
     28     key[x]=L[x]=R[x]=d;
     29     tot[x]=1;mark[x]=d;    
     30 }
     31  
     32 void Push_down(int x){
     33     if(mark[x]!=-1){
     34         Mark(ch[x][0],mark[x]);
     35         Mark(ch[x][1],mark[x]);
     36         mark[x]=-1;
     37     }
     38     if(flip[x]){
     39         Flip(ch[x][0]);
     40         Flip(ch[x][1]);
     41         flip[x]=0;
     42     }
     43 }
     44  
     45 void Rotate(int x){
     46     int y=fa[x],g=fa[y],c=ch[y][1]==x;
     47     ch[y][c]=ch[x][c^1];fa[ch[y][c]]=y;
     48     ch[x][c^1]=y;fa[y]=x;fa[x]=g;
     49     if(g)ch[g][ch[g][1]==y]=x;
     50     Push_up(y);
     51 }
     52  
     53 void Splay(int x,int g=0){
     54     for(int y;(y=fa[x])!=g;Rotate(x))
     55         if(fa[y]!=g)    
     56             Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
     57     Push_up(x);        
     58     if(!g)rt=x;    
     59 }
     60  
     61 int Build(int x,int l,int r){
     62     if(l>r)return 0;
     63     int mid=(l+r)>>1;
     64     ch[mid][0]=Build(mid,l,mid-1);
     65     if(mid!=1&&mid!=n+2)    
     66         scanf("%d",&key[mid]);    
     67     ch[mid][1]=Build(mid,mid+1,r);
     68     sz[mid]=1;mark[mid]=-1;
     69     fa[mid]=x;Push_up(mid);
     70     return mid;
     71 }
     72  
     73 int Get_ID(int k){
     74     int p=rt;
     75     while(true){
     76         Push_down(p);
     77         if(sz[ch[p][0]]+1==k)break;
     78         if(sz[ch[p][0]]+1<k)k-=sz[ch[p][0]]+1,p=ch[p][1];
     79         else p=ch[p][0];    
     80     }
     81     return p;
     82 }
     83 
     84 int main(){
     85 #ifndef ONLINE_JUDGE
     86     freopen("necklace.in","r",stdin);
     87     freopen("necklace.out","w",stdout);
     88 #endif
     89     scanf("%d%d",&n,&c);
     90     rt=Build(0,1,n+2);
     91     scanf("%d",&Q);
     92     while(Q--){
     93         scanf("%s",op);
     94         if(op[0]=='R'){
     95             scanf("%d",&d);d%=n;
     96             if(d==0)continue;
     97             Splay(Get_ID(n-d+1));
     98             Splay(Get_ID(n+2),rt);
     99             int tmp=ch[ch[rt][1]][0];
    100             ch[ch[rt][1]][0]=0;
    101             Splay(Get_ID(1));
    102             Splay(Get_ID(2),rt);
    103             ch[ch[rt][1]][0]=tmp;
    104             fa[tmp]=ch[rt][1];
    105         }
    106         else if(op[0]=='F'){
    107             Splay(Get_ID(2));
    108             Splay(Get_ID(n+2),rt);
    109             Flip(ch[ch[rt][1]][0]);
    110         }
    111         else if(op[0]=='S'){
    112             scanf("%d%d",&l,&r);
    113             if(l>r)swap(l,r);
    114             if(l==r)continue;
    115             Splay(Get_ID(l+1));
    116             Splay(Get_ID(r+1),rt);
    117             swap(key[rt],key[ch[rt][1]]);
    118         }
    119         else if(op[0]=='P'){
    120             scanf("%d%d%d",&l,&r,&d);
    121             if(l<=r){
    122                 Splay(Get_ID(l));
    123                 Splay(Get_ID(r+2),rt);
    124                 Mark(ch[ch[rt][1]][0],d);
    125             }
    126             else{
    127                 Splay(Get_ID(l));
    128                 Splay(Get_ID(n+2),rt);
    129                 Mark(ch[ch[rt][1]][0],d);
    130                 Splay(Get_ID(1));
    131                 Splay(Get_ID(r+2),rt);
    132                 Mark(ch[ch[rt][1]][0],d);
    133             }
    134         }
    135         else if(op[0]=='C'&&op[1]!='S'){
    136             Splay(Get_ID(1));
    137             Splay(Get_ID(n+2),rt);
    138             if(L[ch[ch[rt][1]][0]]==R[ch[ch[rt][1]][0]]&&tot[ch[ch[rt][1]][0]]>1)
    139                 printf("%d
    ",tot[ch[ch[rt][1]][0]]-1);
    140             else
    141                 printf("%d
    ",tot[ch[ch[rt][1]][0]]);
    142         }
    143         else if(op[0]=='C'&&op[1]=='S'){
    144             scanf("%d%d",&l,&r);
    145             if(l<=r){
    146                 Splay(Get_ID(l));
    147                 Splay(Get_ID(r+2),rt);
    148                 printf("%d
    ",tot[ch[ch[rt][1]][0]]);
    149             }
    150             else{
    151                 int ans=0;
    152                 Splay(Get_ID(l));
    153                 Splay(Get_ID(n+2),rt);
    154                 ans+=tot[ch[ch[rt][1]][0]];
    155                 Splay(Get_ID(1));
    156                 Splay(Get_ID(r+2),rt);
    157                 ans+=tot[ch[ch[rt][1]][0]];
    158                 Splay(Get_ID(1));
    159                 Splay(Get_ID(n+2),rt);
    160                 if(L[ch[ch[rt][1]][0]]==R[ch[ch[rt][1]][0]])
    161                     ans-=1;
    162                 printf("%d
    ",ans);    
    163             }    
    164         }
    165     }    
    166     return 0;
    167 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    应用程序发生异常,未知的软件异常0x0eedfade,位置为0x0000001355C
    关于条件表达式的理解
    *p++、*++p、(*p)++、++(*p)的比较
    排序算法01_选择排序
    递归_汉诺塔问题
    排序算法00_冒泡排序
    深入理解C语言
    虚拟机_第一篇---创建Linux虚拟机
    虚拟机_第〇篇---虚拟机的下载安装与功能简介
    对i++与++i的理解
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5558385.html
Copyright © 2020-2023  润新知