1493: [NOI2007]项链工厂

1493: [NOI2007]项链工厂

Time Limit: 30 Sec Memory Limit: 64 MB
Submit: 1839 Solved: 762
[Submit][Status][Discuss]

Description

T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。

最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。该项链自助生产系

统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的

项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能

帮助T公司编写一个软件模拟系统吗?一条项链包含 N 个珠子,每个珠子的颜色是 1,2,…,c 中的一种。项链

被固定在一个平板上,平板的某个位置被标记位置 1 ,按顺时针方向其他位置被记为 2,3,…,N。

fff(1).png

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

fa.png

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


1437515-20181101112817318-1999327536.jpg

写之前突然想到可以开两倍数组啊!

于是欢乐的做出了有史以来最错误的一个决定
1437515-20181101113331113-712486676.jpg
数据结构反人类啊啊啊啊啊啊啊啊啊
然后我还是意志坚定的把我两倍数组的蜜汁程序写完了?↓
1437515-20181101114027868-1810438100.jpg


#include<iostream>
#include<cstdio>

using namespace std;

int i,m,n,j,ss,d[3000001],c[500010],zl[3000001],zr[3000001],b,g,h,lazy[3000001],x,y;
char ch[100];
void update(int now)
{
    d[now]=d[now*2]+d[now*2+1];
    if(zr[now*2]==zl[now*2+1]) d[now]-=1;
    zl[now]=zl[now*2], zr[now]=zr[now*2+1];
}

void down(int now)
{
    if(!lazy[now]) return ;
    lazy[now*2]= lazy[now*2+1]= lazy[now];
    d[now*2]=d[now*2+1]=1; d[now]=1;
    zl[now*2]=zr[now*2]=zl[now*2+1]=zr[now*2+1]=lazy[now];
    lazy[now]=0;
}

void built(int now,int l,int r)
{
    if(l==r) 
    {
        int w=l; if(w>n) w-=n;
        zl[now]=zr[now]=c[w];
        d[now]=1;
        return ;
    }
    int mid=(l+r)>>1;
    built(now*2,l,mid);
    built(now*2+1,mid+1,r);
    update(now);
}

int find(int now,int l,int r,int w)
{
    if(l==r) return zr[now];
    int mid=(l+r)>>1; down(now);
    if(w>mid) return find(now*2+1,mid+1,r,w);
    else return find(now*2,l,mid,w);
}

void gai(int now,int l,int r,int w,int z)
{
    if(l==r) 
    {
        d[now]=1;
        zr[now]=zl[now]=z;
        return ; 
    }
    int mid=(l+r)>>1;
    down(now);
    if(w<=mid) gai(now*2,l,mid,w,z);
    else gai(now*2+1,mid+1,r,w,z);
    update(now);
}

void modify(int now,int l,int r,int ll,int rr,int z)
{
    if(l>=ll && r<=rr) 
    {
        lazy[now]=zl[now]=zr[now]=z;
        d[now]=1; return ;
    }
    int mid=(l+r)>>1; down(now);
    if(mid>=ll) modify(now*2,l,mid,ll,rr,z);
    if(mid<rr) modify(now*2+1, mid+1,r,ll,rr,z);
    update(now);
}

int ask(int now,int l,int r,int ll,int rr)
{
    if(l>=ll && r<=rr) return d[now];
    int mid=(l+r)>>1,ans=0;
    down(now);
    if(ll<=mid) ans+=ask(now*2,l,mid,ll,rr);
    if(rr>mid) ans+=ask(now*2+1,mid+1,r,ll,rr);
    if(ll<=mid && rr>mid && zr[now*2]==zl[now*2+1]) ans-=1;
    return ans;
}

int main()
{
    scanf("%d%d",&n,&ss);
    for(i=1;i<=n;i++) scanf("%d",&c[i]);
    built(1,1,2*n);
    scanf("%d",&m);
    x=n+1, y=n+n;
    for(i=1;i<=m;i++)
    {
        scanf("%s",ch);
        if(ch[0]=='R')
        {
            int k;
            scanf("%d",&k);
            if(b)x+=k, y+=k; else x-=k, y-=k;
            if(y>2*n) y-=n, x-=n;
            if(x<=0) x+=n, y+=n;
        }
        if(ch[0]=='F') 
        {
            b^=1;
            if(b) x+=1, y+=1;
            else x-=1, y-=1;
            if(x<=0) x+=n, y+=n; 
            if(y>2*n) y-=n, x-=n;
        }
        if(ch[0]=='S')
        {
            scanf("%d%d",&g,&h);
            int op,oq;
            if(b) op=y-g+1, oq=y-h+1;
            else op=x+g-1, oq=x+h-1;
            int t=find(1,1,2*n,op), k=find(1,1,2*n,oq);
            gai(1,1,2*n,op,k); gai(1,1,2*n,oq,t);
            if(op>n) op-=n; else op+=n;
            if(oq>n) oq-=n; else oq+=n;
            gai(1,1,2*n,op,k); gai(1,1,2*n,oq,t);
        }
        if(ch[0]=='P')
        {
            int k;
            scanf("%d%d%d",&g,&h,&k);
            int op,oq;
            if(b) op=y-h+1, oq=y-g+1;
            else op=x+g-1, oq=x+h-1;
            if(oq<op) 
            {
                modify(1,1,2*n,x,oq,k);
                modify(1,1,2*n,op,y,k);
                
                if(oq>n) 
                {
                    if(x<n) modify(1,1,2*n,x+n,n+n,k), modify(1,1,2*n,1,oq-n,k);
                    else modify(1,1,2*n,x-n,oq-n,k);
                }
                else modify(1,1,2*n,x+n,oq+n,k);
                if(op<n)
                {
                    if(y>n) modify(1,1,2*n,op+n,n+n,k),modify(1,1,2*n,1,y-n,k);
                    else modify(1,1,2*n,op+n,y+n,k);
                }
                else  modify(1,1,2*n,op-n,y-n,k);
            }
            else 
            {
                modify(1,1,2*n,op,oq,k);
                if(op<n && oq>n) modify(1,1,2*n,op+n,2*n,k),modify(1,1,2*n,1,oq-n,k);
                else if(op>n) modify(1,1,2*n,op-n,oq-n,k);
                else modify(1,1,2*n,op+n,oq+n,k);
            }   
        }
        if(ch[0]=='C' && ch[1]=='S') 
        {
            scanf("%d%d",&g,&h);
            
            int op,oq;
            if(b) op=y-h+1, oq=y-g+1;
            else op=x+g-1, oq=x+h-1;
            if(oq<op) oq+=n;
            if(op>n) op-=n, oq-=n;
            int k=ask(1,1,2*n,op,oq);
            printf("%d\n",k);
        }
        if(ch[0]=='C' && ch[1]!='S') 
        {
            int k=ask(1,1,2*n,x,y);
            if(k!=1 && find(1,1,2*n,x)==find(1,1,2*n,y)) k-=1;
            printf("%d\n",k);
        }
        
    }
}

转载于:https://www.cnblogs.com/ZUTTER/p/9888367.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值