一道权值线段树的题,比较裸
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<vector> #include<cmath> #include<map> #include<set> #include<stack> #define INF 0x3f3f3f3f #define EXP 0.00000001 #define MOD 1000000007 #define MAXN 100005 #define PI acos(-1.0) #define ltree 2*id,ll,mid #define rtree 2*id+1,mid+1,rr #define mem(a) memset(a,0,sizeof(a)) typedef long long LL; using namespace std; int tree[1000005]; int add=0; int lazy[1000005]; char op[20]; void Pushdown(int id) { lazy[id]=0; lazy[id<<1]=lazy[id<<1|1]=1; tree[id<<1]=tree[id<<1|1]=0; } void Update(int id,int ll,int rr,int x,int v) { tree[id]+=v; int mid=(ll+rr)/2; if(ll==rr) return; if(lazy[id]) Pushdown(id); if(x<=mid) Update(ltree,x,v); else Update(rtree,x,v); } int Del(int id,int ll,int rr,int mi) { if(rr<=mi) { int res=tree[id]; tree[id]=0; lazy[id]=1; return res; } if(lazy[id]) Pushdown(id); int mid=(ll+rr)/2; int res=Del(ltree,mi); if(mid<=mi-1) res+=Del(rtree,mi); tree[id]-=res; return res; } int Kthmin(int id,int ll,int rr,int k) { if(ll==rr) return ll; if(lazy[id]) Pushdown(id); int mid=(ll+rr)/2; if(tree[id<<1]>=k) return Kthmin(ltree,k); else return Kthmin(rtree,k-tree[id<<1]); } int Rank(int id,int ll,int rr,int x) { if(ll>=x) return tree[id]; if(lazy[id]) Pushdown(id); int mid=(ll+rr)/2; int res=Rank(rtree,x); if(x<=mid) res+=Rank(ltree,x); return res; } int main() { //freopen("test6.in","r",stdin); //freopen("test6.out","w",stdout); int n; scanf("%d",&n); int ans=0; mem(tree); mem(lazy); add=0; while(n--) { int x; scanf("%s%d",&op,&x); if(op[0]=='I') Update(1,0,300000,x-add+100000,1); else if(op[0]=='A') add+=x; else if(op[0]=='D') ans+=Del(1,0,300000,x-add+100000); else if(op[0]=='M') { if(x>tree[1]) printf("-1\n"); else printf("%d\n",Kthmin(1,0,300000,x)+add-100000); } else { printf("%d\n",Rank(1,0,300000,x-add)); } } printf("%d\n",ans); return 0; }