#树状数组#CF461C Appleman and a Sheet of Paper
分析
可以发现往左翻太多相当于往右翻一点,所以如果翻的位置超过一半那么打一个取反标记再另一边翻转,
用树状数组维护当前厚度,时间复杂度 \(O(n\log^2 n)\)
代码
#include <cstdio>
#include <cctype>
using namespace std;
int n,Q,L,R,c[100011],you;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
void update(int x,int y){
for (;x<=n;x+=-x&x) c[x]+=y;
}
int query(int x){
int ans=0;
for (;x;x-=-x&x) ans+=c[x];
return ans;
}
int main(){
n=iut(),Q=iut(),L=1,R=n;
for (int i=1;i<=n;++i) c[i]=-i&i;
for (int i=1;i<=Q;++i){
int opt=iut(),half=(R-L+1)>>1;
if (opt==1){
int x=iut();
if (you){
if (x<=half){
for (int i=R;i>R-x;--i){
int t=query(i)-query(i-1);
update(R-x-(i-1-(R-x)),t);
}
R-=x;
}else{
x=R-L+1-x;
for (int i=L;i<L+x;++i){
int t=query(i)-query(i-1);
update(L+x+((L+x)-i-1),t);
}
you^=1,L+=x;
}
}else{
if (x<=half){
for (int i=L;i<L+x;++i){
int t=query(i)-query(i-1);
update(L+x+((L+x)-i-1),t);
}
L+=x;
}else{
x=R-L+1-x;
for (int i=R;i>R-x;--i){
int t=query(i)-query(i-1);
update(R-x-(i-1-(R-x)),t);
}
you^=1,R-=x;
}
}
}else{
int l=iut(),r=iut();
if (you) print(query(R-l)-query(R-r));
else print(query(L+r-1)-query(L+l-1));
putchar(10);
}
}
return 0;
}