/*此题操作麻烦之处就是可能折叠过去后超过当前的右边界
* 如果超过右边界可以等效为将右边的向左折,相当于翻转了一次,标记rev=1,
* 下次再进行折叠操作的时候就看成起始端在右边
*
*/
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 100000+10;
int n,q;
int l,r,c[maxn],type;
inline void add(int x,int val)
{
while(x<=maxn)
{
c[x]+=val;
x+=x&(-x);
}
}
inline int Read(){
static int r, sign;
static char c;
r = 0, sign = 1;
do c = getchar(); while(c != '-' && (c < '0' || c > '9'));
if( c == '-')sign = -1, c = getchar();
while( c >= '0' && c <='9') r = r*10 +(int)(c - '0'), c = getchar();
return sign * r;
}
inline int read(int x)
{
int ans = 0;
while(x>0)
{
ans+=c[x];
x-=x&(-x);
}
return ans;
}
int main()
{
n=Read();q=Read();
int s=0,t=n,rev=0;
for(int i=1;i<=n;i++)
add(i,1);
while(q--)
{
type=Read();
if(type==1)
{
l=Read();
if(rev)
{
int len = t-s;
if(2*l>len)
{
rev=0;
int cnt = 0;
for(int i=s+len-l;i>s;i--)
{
cnt++;
int tmp = read(i)-read(i-1);
add(i,-tmp);
add(s+len-l+cnt,tmp);
}
s+=len-l;
}
else
{
int cnt=0;
for(int i=t-l;i<t;i++)
{
int tmp = read(i+1)-read(i);
add(i+1,-tmp);
add(t-l-cnt,tmp);
cnt++;
}
t-=l;
}
}
else
{
int len = t-s;
if(2*l>len)
{
rev=1;
int cnt =0;
for(int i = s+l;i<t;i++)
{
int tmp =read(i+1)-read(i);
add(i+1,-tmp);
add(s+l-cnt,tmp);
cnt++;
}
t=s+l;
}
else
{
int cnt = 0;
for(int i=s+l;i>s;i--)
{
cnt++;
int tmp= read(i)-read(i-1);
add(i,-tmp);
add(s+l+cnt,tmp);
}
s+=l;
}
}
}
else
{
l=Read();r=Read();
if(rev)
{
int ans=read(t-l)-read(t-r);
printf("%d\n",ans);
}
else
{
int ans =read(s+r)-read(s+l);
printf("%d\n",ans);
}
}
}
return 0;
}
CF 【树状数组】461C. Appleman and a Sheet of Paper
最新推荐文章于 2022-04-01 11:12:37 发布