P1198 [JSOI2008]最大数
P1198 [JSOI2008]最大数
2017-09-04
Description
现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。 2、 插入操作。语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。
Input
第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0
Output
对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。
Sample Input
5 100
A 96
Q 1
A 97
Q 1
Q 2
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
96
93
96
93
96
bz的神机子,我不想再看到它.....
线段树维护区间最大值,每一次插入一个数就相当于单点修改,每一次修改都是log m,时间复杂度m*log m,就是这个在线很烦啊...
注意线段树边界,因为会有负数,所以不能简单的tr[k]=max(tr[k<<1],tr[k<<1|1])想想为什么...反正这是一边过的...
再也不用scanf读入字符了....
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; int read(){ char ch=getchar(); int an=0,f=1; while(!('0'<=ch&&ch<='9')){if(ch=='-')f=-f;ch=getchar();} while('0'<=ch&&ch<='9'){an=an*10+ch-'0';ch=getchar();} return an*f; } int D,M; struct saber{ int l,r,Ma; }tr[200000*4+99]; void build(int k,int l,int r){ int mid=(l+r)>>1; tr[k].l=l;tr[k].r=r; if(l==r)return; build(k<<1,l,mid); build(k<<1|1,mid+1,r); } void add(int k,int shu,int data){ int l=tr[k].l,r=tr[k].r; int mid=(l+r)>>1; if(l==r&&l==shu){tr[k].Ma=data;return;} if(shu<=mid){add(k<<1,shu,data);} else add(k<<1|1,shu,data); tr[k].Ma=max(tr[k].Ma,data); } int ask(int k,int i,int j){ int l=tr[k].l,r=tr[k].r; if(l==i&&r==j){return tr[k].Ma;} int mid=(l+r)>>1; if(mid>=j){return ask(k<<1,i,j);} else if(i>mid){return ask(k<<1|1,i,j);} else return max(ask(k<<1,i,mid),ask(k<<1|1,mid+1,j)); } char c;int x; int re,tot; int main(){ M=read();D=read(); build(1,1,M); for(int i=1;i<=M;i++){ cin>>c;x=read(); if(c=='Q'){re=ask(1,tot+1-x,tot);printf("%d\n",re);} else {tot++;add(1,tot,(re+x)%D);} } return 0; }
by:s_a_b_e_r
表示楼上线段树dalao……写线段树各种错的我qwq
看着旁边s开始敲线段树,我默默的开始写树状数组
求区间最值这种事,树状数组还是能做到的
安利一发讲树状数组的博客
树状数组区间最值求法就是从这学来的
#include<cstdio> #include<iostream> using namespace std; const int N=200099; int m,d,a[N],c[N],t,len; int lowbit(int x){return x&(-x);} int found(int l,int r) { int ans=0; while (r>=l) { ans=max(a[r],ans);--r; for(;r-lowbit(r)>=l;r-=lowbit(r)) ans=max(c[r],ans); } return ans; } void add(int k,int x) { while(k<=N) { c[k]=max(c[k],x); k+=lowbit(k); } } int main() { scanf("%d%d",&m,&d); for(int i=1;i<=m;++i) { char x;int y; cin>>x>>y; if(x=='Q') { t=found(len-y+1,len); printf("%d\n",t); } else if(x=='A') { y=(y+t)%d; a[++len]=y; add(len,a[len]); } } return 0; }
表示bz有毒……最近各种迷之RE
以及据说这题单调队列单调栈都可以解决……?
s:我不想到bz交题了QAQ.....
w:+1,bz有毒qwq