bzoj1012-(线段树)

来源:互联网 发布:杀师案 知乎 编辑:程序博客网 时间:2024/05/18 15:07

现在请求你维护一个数列,要求提供以下两种操作: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 Input
5 100A 96Q 1A 97Q 1Q 2
Sample Output
969396

代码:

#include<iostream>#include<string>#include<cstdio>#include<algorithm>#include<cmath>#include<iomanip>#include<queue>#include<cstring>#include<map>using namespace std;typedef long long ll;#define M 200005#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1ll d,t,len,n,x;ll tree[M<<2];int a[M];void pushup(int rt){    tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);}void update(int pos,ll v,int l,int r,int rt){    if(l==r)    {        tree[rt]=v;        return ;    }    int m=(l+r)>>1;    if(pos<=m) update(pos,v,lson);    else update(pos,v,rson);    pushup(rt);}ll query(int ql,int qr,int l,int r,int rt){    if(ql<=l&&qr>=r)    {        return tree[rt];    }    int m=(l+r)>>1;    ll ret=-1000000000;    if(ql<=m) ret=max(ret,query(ql,qr,lson));    if(qr>m) ret=max(ret,query(ql,qr,rson));    return ret;}int main(){    int i,num;    char ch;    scanf("%d%lld",&num,&d);    for(int cas=1;cas<=num;cas++)    {        getchar();        ch=getchar();        scanf("%lld",&x);        len++;        if(ch=='Q')        {            int l=a[n-x+1];            int r=a[n];            t=query(l,r,1,num,1);            printf("%lld\n",t);        }        else        {            x=(x%d+t%d)%d;            n++;            a[n]=len;            update(len,x,1,num,1);        }    }    return 0;}


原创粉丝点击