【BZOJ1012】【JSOI2008】最大数
难得的水题,应该是这题是T1吧,终于没看别人代码,然而思路还是看题解点了一下
原题:
现在请求你维护一个数列,要求提供以下两种操作:1、 查询操作。语法:Q L 功能:查询当前数列中末尾L
个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。2、 插入操作。语法:A n 功能:将n加
上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取
模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个
数。
M <= 200,000
……刚开始看的时候还以为是可持久化……
看题解后发现这就一水题,只有200000个操作,所以整个线段长度不会太长,而且因为只在末尾插入而且没有删除,所以就可以直接记录一个长度,插入一个长度++,并把长度对应的位置buff一下即可
做题时还是要考虑特殊性而不是一般性
要分析数据量,算一下复杂度看能不能搞一个奇奇怪怪的算法水过
代码;
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 int read(){int z=0,mark=1; char ch=getchar(); 8 while(ch<'0'||ch>'9'){if(ch=='-')mark=-1; ch=getchar();} 9 while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0'; ch=getchar();} 10 return z*mark; 11 } 12 int n=0,m,mo; 13 struct dcd{int sleft,sright,mid,svalue;}tree[2100000]; 14 void get_SegmentTree(int x,int _left,int _right){ 15 tree[x].sleft=_left,tree[x].sright=_right,tree[x].mid=(_left+_right)/2,tree[x].svalue=0; 16 if(_left!=_right) get_SegmentTree(x<<1,_left,tree[x].mid),get_SegmentTree(x<<1|1,tree[x].mid+1,_right); 17 } 18 void buff(int x,int _id,int _value){ 19 if(tree[x].sleft==tree[x].sright && _id==tree[x].sleft) tree[x].svalue=_value; 20 else{ 21 if(_id<=tree[x].mid) buff(x<<1,_id,_value); 22 else buff(x<<1|1,_id,_value); 23 tree[x].svalue=max(tree[x<<1].svalue,tree[x<<1|1].svalue); 24 } 25 } 26 int search(int x,int _left,int _right){ 27 if(tree[x].sleft==_left && tree[x].sright==_right) return tree[x].svalue; 28 else if(_left<=tree[x].mid && _right>tree[x].mid) return max(search(x<<1,_left,tree[x].mid),search(x<<1|1,tree[x].mid+1,_right)); 29 else if(_right<=tree[x].mid) return search(x<<1,_left,_right); 30 else return search(x<<1|1,_left,_right); 31 } 32 int main(){//freopen("ddd.in","r",stdin); 33 cin>>m>>mo; 34 get_SegmentTree(1,1,m); 35 int last_ans=0; 36 char _left; int _right; 37 while(m --> 0){ 38 _left=getchar(); while(_left!='A' && _left!='Q') _left=getchar(); 39 _right=read(); 40 if(_left=='A'){ n++; buff(1,n,(_right+last_ans)%mo);} 41 else printf("%d\n",last_ans=search(1,n-_right+1,n)); 42 } 43 return 0; 44 }