#樹狀陣列#CF461C Appleman and a Sheet of Paper
阿新 • • 發佈:2022-03-22
分析
可以發現往左翻太多相當於往右翻一點,所以如果翻的位置超過一半那麼打一個取反標記再另一邊翻轉,
用樹狀陣列維護當前厚度,時間複雜度 \(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; }