这题可以说是模板题了。

只需要预先开好m大小的线段树,就好了,这就可以处理加点的问题。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
inline ll read(){
    ll t=1,num=0;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return num*t;
}
inline ll max(ll a,ll b){return a>b?a:b;}
const ll maxn=200010,INF=0x7fffffff;
ll m,d,t[maxn*3];
void build(ll ro,ll l,ll r){
    if(l==r){t[ro]=0;return;}
    ll mid=(l+r)>>1;
    build(ro*2,l,mid);build(ro*2+1,mid+1,r);
    t[ro]=max(t[ro*2],t[ro*2+1]);
}
ll ask(ll ro,ll l,ll r,ll x,ll y){
    if(x>r||y<l)return -INF;
    if(x<=l&&r<=y)return t[ro];
    ll mid=(l+r)>>1;
    return max(ask(ro*2,l,mid,x,y),ask(ro*2+1,mid+1,r,x,y));
}
void change(ll ro,ll l,ll r,ll x,ll add){
    if(l==r){if(l==x)t[ro]=(t[ro]+add)%d;return;}
    ll mid=(l+r)>>1;
    if(x<=mid)change(ro*2,l,mid,x,add);
    else change(ro*2+1,mid+1,r,x,add);
    t[ro]=max(t[ro*2],t[ro*2+1]);
}
int main()
{
    m=read();d=read();
    ll tmp=0,cnt=0;build(1,1,m);
    for(ll i=1;i<=m;i++){
        char c[3];scanf("%s",c);
        if(c[0]=='A'){
            ll x=read()+tmp;
            change(1,1,m,++cnt,x);
        }
        else{
            ll x=read();
            tmp=ask(1,1,m,cnt-x+1,cnt);
            printf("%d\n",tmp);
        }
    }
    return 0;
}

然而,我一开始交上去,wa了,too few or too much lines

因为我读入的时候是getchar读入字符,快速读入数字。

改成scanf就AC了。

本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。

posted on 2017-08-14 21:49  Yzyet  阅读(206)  评论(0编辑  收藏  举报