两种做法:线段树和树状数组
TLE了几次= = 主要是cout
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 30000+10; const int maxm = 65535*3+1; int n,num[maxn],C[maxm]; inline int lowbit(int x){ return x&(-x); } int sum(int x){ int ret = 0; while(x > 0){ ret += C[x]; x -= lowbit(x); } return ret; } void add(int x,int d){ while(x <= maxm) { C[x] += d; x += lowbit(x); } } int find(int x){ int L = 1,R = maxm; while(L<=R){ int mid = (L+R)>>1; if(sum(mid)<=x){ L = mid+1; }else{ R = mid-1; } } return L; } int main(){ scanf("%d",&n); memset(C,0,sizeof(C)); for(int i = 1; i <= n; i++){ scanf("%d",&num[i]); add(num[i],1); } int m; scanf("%d",&m); while(m--){ char task[40]; int a,b; scanf("%s",task); if(task[0]=='Q'){ scanf("%d",&a); if(a>n) printf("-1\n"); else printf("%d\n",find(n-a)); } else if(task[0]=='A'){ scanf("%d%d",&a,&b); if(num[a]>0){ add(num[a],-1); num[a]-=b; if(num[a]>0) add(num[a],1); else n--; } } else{ scanf("%d%d",&a,&b); if(num[a]>0){ add(num[a],-1); num[a]+=b; add(num[a],1); } } } printf("%d\n",n); return 0; }
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 30000+10; const int maxm = 65535*3+1; struct node{ int lson,rson,sum; int mid(){ return lson+(rson-lson)/2; } }tree[maxm*4]; int n,num[maxn]; void pushup(int pos){ tree[pos].sum = tree[pos*2+1].sum+tree[pos*2].sum; } void build(int l,int r,int pos){ tree[pos].lson = l; tree[pos].rson = r; tree[pos].sum = 0; if(l == r) return; int mid = tree[pos].mid(); build(l,mid,pos*2); build(mid+1,r,pos*2+1); } void update(int x,int pos,int k){ if(tree[pos].lson==tree[pos].rson && tree[pos].lson==x){ tree[pos].sum += k; }else{ int mid = tree[pos].mid(); if(x<=mid) update(x,pos*2,k); else update(x,pos*2+1,k); pushup(pos); } } int query(int L,int R,int pos){ if(tree[pos].lson >= L && tree[pos].rson<=R) return tree[pos].sum; int mid = tree[pos].mid(); if(R <= mid) return query(L,R,pos*2); else if(L > mid) return query(L,R,pos*2+1); else return query(L,mid,pos*2)+query(mid+1,R,pos*2+1); } int find(int x){ int L = 1,R = maxm; while(L<=R){ int mid = (L+R)/2; if(query(1,mid,1)<=x){ L = mid+1; }else{ R = mid-1; } } return L; } int main(){ scanf("%d",&n); int maxk = 0; build(1,maxm,1); for(int i = 1; i <= n; i++){ scanf("%d",&num[i]); update(num[i],1,1); } int m; scanf("%d",&m); while(m--){ char task[40]; int a,b; scanf("%s",task); if(task[0]=='Q'){ scanf("%d",&a); if(a>n) printf("-1\n"); else printf("%d\n",find(n-a)); } else if(task[0]=='A'){ scanf("%d%d",&a,&b); if(num[a]>0){ update(num[a],1,-1); num[a]-=b; if(num[a]>0) update(num[a],1,1); else n--; } } else{ scanf("%d%d",&a,&b); if(num[a]>0){ update(num[a],1,-1); num[a]+=b; update(num[a],1,1); } } } printf("%d\n",n); return 0; }