首页 写随笔

cdcq(本博客废弃!现用博客:https://www.cnblogs.com/cdcq/)

本博客废弃!现用博客:https://www.cnblogs.com/cdcq/

导航

【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 }
View Code

 

posted on 2016-09-30 09:41  cdcq_old  阅读(153)  评论(0编辑  收藏  举报