1. 程式人生 > >不知哪個OJ P3162 數列編輯器 樹狀數組+腦子

不知哪個OJ P3162 數列編輯器 樹狀數組+腦子

++ define fas += 右移 turn 兩個棧 dig edi

P3162 -- 數列編輯器

時間限制:1000MS 內存限制:262144KB數據結構-棧 無

題目描述(editor.cpp)

現在你需要實現一個數列編輯器,一開始,數列為空,光標在開頭位置,編輯器要支持對這個數列進行如下六種操作:

Ix在光標的後面插入一個整數 x,並將光標移到這個新加入的 x 後。

D:刪除光標前的最後一個數字(保證存在),光標位置不變。

L:光標左移一位,如果已經在開頭則不做任何事。

R:光標右移一位,如果已經在結尾則不做任何事。

Q l r:求當前序列中第 l到第 r個數(包含邊界,保證存在)的和。

C p x:將當前序列第 p 個數(保證存在)修改成整數 x

,光標不移動。

輸入格式(editor.in)

第一行,一個整數 n,表示操作的總次數。

n 行,每行是上列六種操作中的一種。

輸出格式(editor.ans)

對每個詢問輸出一行一個整數,表示答案。

樣例輸入

9
I 2
I -1
I 1
Q 1 2
L
D
Q 1 2
I -3
Q 1 2

樣例輸出

1
3
-1

數據規模與約定

Easy:第 1−2 個測試點,1≤n≤5000。

Normal:第 3−4個測試點,不存在 L,R,C 操作。

Hard:第 5−7個測試點,不存在 L,R操作。

Extra:對於 100%的數據,存在全部操作,且 1≤n

≤5×10^5,記當前數列長度為 L,則操作中 −10^9≤x≤10^9,1≤lrL,且 1≤pL


+20分:鏈表

+50分:前綴樹狀數組

正解:建一個前綴樹狀數組,建一個後綴樹狀數組,中間夾著光標,如果你不懶再開兩個棧,存兩個數狀數組中的數

移動光標就是,把一個棧的數彈到另一個裏面,把一個樹狀數組的數彈到另一個裏面。。。剩下操作就直接求就好了。。。

代碼(我懶沒有棧)

#include<cstdio>
#include<iostream>
#define ll long long
#define
R register ll using namespace std; const int N=500010; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int n,cntl,cntr; ll c[2][N]; inline int lbt(int x) {return x&-x;} inline void add(int d,int pos,int x) {for(;pos<=n;pos+=lbt(pos)) c[d][pos]+=x;} inline ll query(int d,int pos) { R ret=0; for(;pos;pos-=lbt(pos)) ret+=c[d][pos]; return ret; } signed main() { n=g(); for(R i=1;i<=n;++i) { register char ch; R x,l,r; while(!isalpha(ch=getchar())) cerr<<ch; cerr<<ch<<endl; cerr<<"qwq"; cerr<<"fasdgfads"<<cntl<<" "<<cntr<<endl; if(ch==I) x=g(),add(0,++cntl,x); else if(ch==D) x=query(0,cntl)-query(0,cntl-1),add(0,cntl,-x),--cntl; else if(ch==L) {if(cntl>0) x=query(0,cntl)-query(0,cntl-1),add(0,cntl,-x),--cntl,add(1,++cntr,x);} else if(ch==R) {if(cntr>0) x=query(1,cntr)-query(1,cntr-1),add(1,cntr,-x),--cntr,add(0,++cntl,x);} else if(ch==Q) { R ret=0; l=g(),r=g(); if(r<=cntl) printf("%lld\n",query(0,r)-query(0,l-1)); else if(l>cntl) printf("%lld\n",query(1,cntl+cntr-l+1)-query(1,cntl+cntr-r)); else printf("%lld\n",query(0,cntl)-query(0,l-1)+query(1,cntr)-query(1,cntl+cntr-r)); } else if(ch==C) { l=g(),x=g(); if(l<=cntl) r=query(0,l)-query(0,l-1),add(0,l,x-r); else r=query(1,cntl+cntr-l+1)-query(1,cntl+cntr-l),add(1,cntl+cntr-l+1,x-r); } } }

2019.05.06

不知哪個OJ P3162 數列編輯器 樹狀數組+腦子