NC20420. [SHOI2010]滚动的正四面体
描述
输入描述
输入文件的第一行是一个整数n,表示指令串中包含的指令条数。
输入文件的第二行是一个字符串,共包含n个字符,每个字符是“L”“R”“B”之一,表示初始的指令串。
输入文件的第三行是一个整数m,表示你的程序需要处理的操作总数。
接下去m行,每行描述一个操作,为以下两种格式之一:
(1)0 i c:表示把第i个操作改成c,c为“L”“R”“B”之一
(2)1 L R:表示询问第L秒到第R秒内,A面有多少秒朝下
输入文件保证:1<=i<=n,1<=L<=R<=n+1。
输出描述
输出文件对于每一个询问操作依次输出你的程序给出的回答,每个回答为一个整数,占一行。
示例1
输入:
5 LLLLB 3 1 3 6 0 3 R 1 3 6
输出:
2 1
C++(clang++11) 解法, 执行用时: 69ms, 内存消耗: 4984K, 提交时间: 2020-11-13 20:13:56
#include<bits/stdc++.h> using namespace std; const int N=2e5,inf=1<<16; int read(){ int s=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();} return s*f; } int ind[256]; int readc(){ int ch=getchar(); while(ch<'A'||ch>'Z') ch=getchar(); return ind[ch]; } int nx[N][4],c[N][4],ss[32],sp=0; int nx0[3][4]={{1,2,0,3},{1,3,2,0},{1,0,3,2}}; inline void sets(int w,int x){ for(int j=0;j<4;++j)c[w][j]=!(nx[w][j]=nx0[x][j]); } inline void up(int w){ int l=w<<1,r=l^1; for(int j=0;j<4;++j)nx[w][j]=nx[r][nx[l][j]],c[w][j]=c[l][j]+c[r][nx[l][j]]; } int main(){ ind['L']=0;ind['R']=1;ind['B']=2; int n=read(); for(int i=1,x,w;i<=n;++i){x=readc();sets(i+inf-1,x);} for(int i=inf-1;i;--i)up(i); for(int q=read();q;--q) if(read()){ int l=read()-2,r=read()-1,v=0,s=0; if(l>=0){ for(int w=l+inf;w;w>>=1)if(w&1)ss[sp++]=w^1; while(sp){ int w=ss[--sp]; s-=c[w][v]; v=nx[w][v]; } }else ++s; for(int w=r+inf;w;w>>=1)if(w&1)ss[sp++]=w^1; while(sp){ int w=ss[--sp]; s+=c[w][v]; v=nx[w][v]; } printf("%d\n",s); } else{ int w=read()+65535,x=readc(); sets(w,x); for(w>>=1;w;w>>=1)up(w); } return 0; }