標籤:bit ring algorithm pre cpp 維護 using ber 固定
012: [JSOI2008]最大數maxnumberTime Limit: 3 Sec Memory Limit: 162 MB
Description
現在請求你維護一個數列,要求提供以下兩種操作:1、 查詢操作。文法:Q L 功能:查詢當前數列中末尾L
個數中的最大的數,並輸出這個數的值。限制:L不超過當前數列的長度。2、 插入操作。文法:A n 功能:將n加
上t,其中t是最近一次查詢操作的答案(如果還未執行過查詢操作,則t=0),並將所得結果對一個固定的常數D取
模,將所得答案插入到數列的末尾。限制:n是非負整數並且在長整範圍內。注意:初始時數列是空的,沒有一個
數。
Input
第一行兩個整數,M和D,其中M表示操作的個數(M <= 200,000),D如上文中所述,滿足D在longint內。接下來
M行,查詢操作或者插入操作。
Output
對於每一個詢問操作,輸出一行。該行只有一個數,即序列中最後L個數的最大數。
Sample Input5 100
A 96
Q 1
A 97
Q 1
Q 2Sample Output96
93
96好久懶得更新部落格了~~~線段樹水模板題。維護一顆[1,M]線段樹,初始值就不賦。然後開始將A當成單點修改,搞一個記錄序列長度的變數ll,最終Q就是區間查詢最大值[ll-len+1,ll](len就是Q讀入的L)。然後就交一下,無限RE,然後才知道char在bzoj不知道怎麼搞的要scanf,不能cin。漲姿勢了~慘啊!最後其實也聽說樹狀數組可以很快秒殺?給跪了!
#include<iostream>#include<fstream>#include<cstdio>#include<algorithm>#include<string>#include<vector>#include<queue>#include<deque>#include<utility>#include<map>#include<set>#include<cmath>#include<cstdlib>#include<ctime>#include<functional>#include<sstream>#include<cstring>#include<bitset>#include<stack>using namespace std;int m,d,num,len,t,ll;char aq[2];int lef[1000005],rig[1000005],data[1000005];void build(int root,int l,int r){lef[root]=l;rig[root]=r;if(l==r)return ;int mid=(l+r)/2;build(root*2,l,mid);build(root*2+1,mid+1,r);}void modify(int root,int x,int y){if(lef[root]==rig[root]){data[root]=y;return ;}int mid=(lef[root]+rig[root])/2;if(x<=mid)modify(root*2,x,y); else modify(root*2+1,x,y);data[root]=max(data[root*2],data[root*2+1]);}int query(int root,int l,int r){if(l==lef[root] && r==rig[root])return data[root];int mid=(lef[root]+rig[root])/2;if(r<=mid)return query(root*2,l,r);if(l>mid)return query(root*2+1,l,r);return max(query(root*2,l,mid),query(root*2+1,mid+1,r));}int main(){scanf("%d%d",&m,&d);build(1,1,m);for(int i=1;i<=m;i++){scanf("%s",aq);if(aq[0]==‘A‘){scanf("%d",&num);modify(1,++ll,(t%d+num%d)%d);}else{scanf("%d",&len);t=query(1,ll-len+1,ll);printf("%d\n",t);}}return 0;}
BZOJ 1012: [JSOI2008]最大數maxnumber(線段樹)