题意:对于一个数列有两种操作:输出最后L个数中的最大值、将一个数插入到最后。
水水的线段树...一开始直接建好树然后按顺序插入就好了。
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; #define MaxN 200000 #define INF 200000000 int n=0,m,mod,t=0,root=0,tot=0; struct atp { int l,r,lc,rc,data; }a[MaxN*2]; void start(int &t,int l,int r) { tot++; t=tot; a[tot].l=l; a[tot].r=r; a[tot].data=INF; a[tot].rc=a[tot].rc=0; if (l!=r) { int mid=(l+r)/2; start(a[t].lc,l,mid); start(a[t].rc,mid+1,r); } } void insert(int t,int data,int x) { if (a[t].l==a[t].r) { a[t].data=data; return; } if (x<=a[a[t].lc].r) insert(a[t].lc,data,x); else if (x>=a[a[t].rc].l) insert(a[t].rc,data,x); a[t].data=max(a[a[t].lc].data,a[a[t].rc].data); } int find(int t,int l, int r) { if (a[t].l==l && a[t].r==r) return a[t].data; if (r<=a[a[t].lc].r) return find(a[t].lc,l,r); else if (l>=a[a[t].rc].l) return find(a[t].rc,l,r); else return max(find(a[t].lc,l,a[a[t].lc].r),find(a[t].rc,a[a[t].rc].l,r)); } int main() { freopen("in","r",stdin); int x;char ch; scanf("%d%d",&m,&mod);getchar(); start(root,1,m); for (int i=1;i<=m;i++,getchar()) { scanf("%c%d",&ch,&x); if (ch=='Q') printf("%d\n",t=find(root,n-x+1,n)); if (ch=='A') x=(x+t)%mod,insert(root,x,++n); } return 0; }