【bzoj1503】 NOI2004—郁闷的出纳员

http://www.lydsy.com/JudgeOnline/problem.php?id=1503 (题目链接)

题意

  要求维护4种操作:插入一个数,将所有数加上k,将所有数减去k,删去数值小于k的数并计算个数。

Solution

  splay。今天考试的时候询问时忘记下传标记了fuck dog

代码

// bzoj1503
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=500010;
int tr[maxn][2],size[maxn],val[maxn],sum[maxn],fa[maxn],tag[maxn];
int rt,cnt,S,n,ming,tot; void update(int k) {
int l=tr[k][0],r=tr[k][1];
size[k]=size[l]+size[r]+sum[k];
}
void rotate(int x,int &k) {
int y=fa[x],z=fa[y],l,r;
l=tr[y][1]==x;r=l^1;
if (k==y) k=x;
else tr[z][tr[z][1]==y]=x;
fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
tr[y][l]=tr[x][r];tr[x][r]=y;
update(y);update(x);
}
void splay(int x,int &k) {
while (x!=k) {
int y=fa[x],z=fa[y];
if (y!=k) {
if ((tr[z][0]==y) ^ (tr[y][0]==x)) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
void pushdown(int k) {
val[tr[k][1]]+=tag[k];tag[tr[k][1]]+=tag[k];
val[tr[k][0]]+=tag[k];tag[tr[k][0]]+=tag[k];
tag[k]=0;
}
void insert(int x) {
int k=rt,f=0;
while (k) {
if (tag[k]) pushdown(k);f=k;
if (x<val[k]) k=tr[k][0];
else if (x>val[k]) k=tr[k][1];
else {sum[k]++;size[k]++;S++;splay(k,rt);return;}
}
S++;
fa[++cnt]=f;sum[cnt]=size[cnt]=1;val[cnt]=x;tr[f][x>val[f]]=cnt;
splay(cnt,rt);
}
int find(int x,int k) {
if (tag[k]) pushdown(k);
int ans=0;
while (k) {
if (tag[k]) pushdown(k);
if (x==val[k]) return k;
if (x<val[k]) ans=k,k=tr[k][0];
else k=tr[k][1];
}
return ans;
}
void modify(int k) {
val[rt]+=k,tag[rt]+=k;
if (k<0) {
int x=find(ming,rt);
splay(x,rt);
tot+=size[tr[x][0]];S-=size[tr[x][0]];tr[x][0]=0;
}
}
int query(int x,int k) {
if (tag[k]) pushdown(k);
int l=tr[k][0],r=tr[k][1];
if (x>=size[r]+1 && x<=size[r]+sum[k]) return k;
else if (x<=size[r]) return query(x,r);
else return query(x-size[r]-sum[k],l);
}
int main() {
char ch[10];int k;
tot=0;
rt=cnt=1;val[1]=(1<<30);
scanf("%d%d",&n,&ming);
for (int i=1;i<=n;i++) {
scanf("%s%d",ch,&k);
if (ch[0]=='I') {if (k>=ming) insert(k);/*else tot++;*/}
if (ch[0]=='A') modify(k);
if (ch[0]=='S') modify(-k);
if (ch[0]=='F') printf("%d\n",k>S ? -1 : val[query(k,rt)]);
}
printf("%d\n",tot);
return 0;
}

  

上一篇:使用ConfigurationManager类读写配置文件


下一篇:【SQL Server】数据库是单个用户的 无法顺利进行操作 怎么解决