树状数组居然还能求最值…
在http://www.cnblogs.com/iwtwiioi/p/3869868.html 这学的
%%%%%%%%%%%%
每个C[i]管理的是i-lowbit(i)+1~i的max
就像Sum数组一样,不过求1~i的最大值要i向前找log(n)
然后闲的…也很久没写splay了就写了个splay…
接下类应该会刷一些比较好的数据结构题boomshakalaka
/**************************************************************
Problem: 1012
User: humeay
Language: C++
Result: Accepted
Time:764 ms
Memory:2836 kb
****************************************************************/
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x&(-x))
typedef long long LL;
const int maxn = 200005;
const int inf=(1<<28)-1;
int c[maxn],num[maxn];
int mod;
int get_kth(int l,int r)
{
int res=num[r];
while(l<=r)
{
res=max(res,num[r]);
--r;
while(r-l>=lowbit(r))
{
res=max(res,c[r]);
r-=lowbit(r);
}
}
return res;
}
int main()
{
int m;
scanf("%d%d",&m,&mod);
int t=0,cnt=0;
while(m--)
{
char str[5];
int x;
scanf("%s%d",str,&x);
if(str[0]=='Q')
{
printf("%d\n",t=get_kth(cnt-x+1,cnt));
}
else
{
num[++cnt]=(x+t)%mod;
c[cnt]=max(get_kth(cnt-lowbit(cnt)+1,cnt-1),num[cnt]);
}
}
return 0;
}
splay
/**************************************************************
Problem: 1012
User: humeay
Language: C++
Result: Accepted
Time:1876 ms
Memory:8316 kb
****************************************************************/
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x&(-x))
typedef long long LL;
const int maxn = 200005;
const int inf=(1<<28)-1;
int m;
class SSplay
{
#define lson(x) (Son[x][0])
#define rson(x) (Son[x][1])
public:
int Son[maxn][2],Fa[maxn],Size[maxn];
int Sum[maxn],Key[maxn],Lazy[maxn],Max[maxn],Val[maxn];
int root,tots;
void init()
{
root=tots=0;
Son[root][0]=Son[root][1]=Fa[root]=0;
NewNode(root,0,0,-1);NewNode(rson(root),root,m+1,inf);
Size[root]=2;
}
void NewNode(int &x,int pre,int k,int t)
{
x=++tots;
Fa[x]=pre;
Lazy[x]=0;
Size[x]=1;
Val[x]=Max[x]=t;
Sum[x]=Key[x]=k;
Son[x][0]=Son[x][1]=0;
}
void Push_down(int r)
{
if(!Lazy[r]) return ;
Sum[Son[r][0]]+=Size[Son[r][0]]*Lazy[r];
Sum[Son[r][1]]+=Size[Son[r][1]]*Lazy[r];
Key[Son[r][0]]+=Lazy[r];
Key[Son[r][1]]+=Lazy[r];
Lazy[Son[r][0]]+=Lazy[r];
Lazy[Son[r][1]]+=Lazy[r];
Lazy[r]=0;
}
void Push_up(int r)
{
Max[r]=max(Val[r],max(Max[lson(r)],Max[rson(r)]));
Sum[r]=Sum[Son[r][0]]+Sum[Son[r][1]]+Key[r];
Size[r]=Size[Son[r][0]]+Size[Son[r][1]]+1;
}
void Rotate(int x,int kind)//1->right 0->left
//以right为例子
{
int pre=Fa[x];
Push_down(pre);Push_down(x);
Son[pre][!kind]=Son[x][kind];//把rson(x)赋给lson(pre)
Fa[Son[x][kind]]=pre;//把rson(x)的fa指针指向pre
if(Fa[pre])
Son[Fa[pre]][Son[Fa[pre]][1]==pre]=x;//把Fa[pre]的儿子节点指向x
Fa[x]=Fa[pre];//把x的父亲节点修改为Fa[pre]
Son[x][kind]=pre;//把rson(x)改为pre
Fa[pre]=x;//修改pre的父亲节点
Push_up(pre);
}
void Splay(int x,int goal)//goal是转移的目标结点父亲节点
{
Push_down(x);
while(Fa[x]!=goal)
{
int pre=Fa[x];
if(Fa[pre]==goal)
Rotate(x,Son[pre][0]==x);
else
{
int kind=Son[Fa[pre]][0]==pre;//pre是Fa[pre]的kind儿子
if(Son[pre][kind]==x)
Rotate(x,!kind),Rotate(x,kind);
else Rotate(pre,kind),Rotate(x,kind);
}
}
Push_up(x);
if(!goal) root=x;
}
int Insert(int x,int t)//插入后根节点是x
{
int r=root;
while(Son[r][x>Key[r]])
{
if(Key[r]==x)
{
Splay(r,0);
return 0;
}
r=Son[r][x>Key[r]];
}
NewNode(Son[r][x>Key[r]],r,x,t);
Splay(Son[r][x>Key[r]],0);
return 1;
}
void Delete()//删除根节点
{
if(Son[root][0])
{
int r=Son[root][0];
while(Son[root][0])
r=Son[root][1];
Splay(r,root);
Son[r][1]=Son[root][1];//因为x是比root小的最大的,所以rson(x)=0
Fa[Son[r][1]]=r;
root=r;
Fa[r]=0;
}
else
{
int root=Son[root][1];
Fa[root]=0;
}
}
int find_min(int x)
{
int r=Son[root][0];
if(r==0) return inf;
while(Son[r][1]) r=Son[r][1];
return Key[x]-Key[r];
}
int find_max(int x)
{
int r=Son[root][1];
if(r==0) return inf;
while(Son[r][0]) r=Son[r][0];
return Key[r]-Key[x];
}
void print(int r)
{
printf("%d:key=%d fa=%d ",r,Key[r],Fa[r]);
if(Son[r][0]) printf("lson=%d ",Son[r][0]);
if(Son[r][1]) printf("rson=%d ",Son[r][1]);
printf("\n");
if(Son[r][0]) print(Son[r][0]);
if(Son[r][1]) print(Son[r][1]);
}
int Find(int k)
{
int x=root;
Push_down(x);
while(Size[lson(x)]!=k)
{
if(k<Size[lson(x)]) x=lson(x);
else
{
k-=Size[lson(x)]+1;
x=rson(x);
}
Push_down(x);
}
return x;
}
void Add(int l,int r,int x)
{
Splay(Find(l-1),0);Splay(Find(r+1),root);
int now=Son[root][1];
now=Son[now][0];
Lazy[now]+=x;
Sum[now]+=x*Size[now];
Key[now]+=x;
}
int query(int l,int r)
{
Splay(Find(l-1),0);Splay(Find(r+1),root);
return Max[lson(rson(root))];
}
#undef lson(x)
#undef rson(x)
}splay;
int main()
{
int mod;
scanf("%d%d",&m,&mod);
splay.init();
int t=0,cnt=0;
while(m--)
{
char str[5];
int x;
scanf("%s%d",str,&x);
if(str[0]=='A')
{
x=(x+t)%mod;
splay.Insert(++cnt,x);
}
else
{
printf("%d\n",t=splay.query(cnt-x+1,cnt));
}
}
return 0;
}