标签:区间 turn oid add 支持 最大数 端点 ring ret
这个题最大的难点在于插入,实际上我们可以假设这是一棵早就建好的线段树,插入只是单点赋值而已
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; typedef long long lo; lo m,d,t,tail,x; char s; struct in { lo l,r,mx; }ter[800080]; inline void build(lo l,lo r,lo w)//我们可以把它看做这是一棵有m个点的线段树,那么只要支持单点修改和区间查询即可 { ter[w].l=l,ter[w].r=r,ter[w].mx=0; if(l==r) return; lo mid=l+r>>1; build(l,mid,w<<1),build(mid+1,r,w<<1|1); } inline void up(lo w) { ter[w].mx=max(ter[w<<1].mx,ter[w<<1|1].mx); } void add(lo l,lo z,lo n,lo w) { if(ter[w].l==ter[w].r&&ter[w].l==l) { ter[w].mx=(z+n)%d;return;//单点赋值 } lo mid=ter[w].l+ter[w].r>>1; if(l<=mid) add(l,z,n,w<<1); else add(l,z,n,w<<1|1); up(w); } lo ask(lo l,lo r,lo w) { if(ter[w].l==l&&ter[w].r==r) return ter[w].mx; lo mid=ter[w].l+ter[w].r>>1; if(r<=mid) return ask(l,r,w<<1); else if(l>mid) return ask(l,r,w<<1|1); else return max(ask(l,mid,w<<1),ask(mid+1,r,w<<1|1)); } int main() { scanf("%lld%lld",&m,&d); build(1,m,1); for(int i=1;i<=m;i++) { cin>>s>>x; if(s==‘A‘) add(++tail,t,x,1); else { t=ask(tail-x+1,tail,1);printf("%lld\n",t); }//需要记录下有用的区间右端点和上次所查询的答案 } }
标签:区间 turn oid add 支持 最大数 端点 ring ret
原文地址:http://www.cnblogs.com/Loi-dfkdsmbd/p/7746343.html