HDU2852【樹狀陣列+二分】
阿新 • • 發佈:2019-01-26
額。。有點遺忘了樹狀陣列特性了。。印象中一直是字首和,然後一定要記住樹狀陣列是把給出的值(值太大可能可以離散化)也就是點到了區間,然後這個點存的值就是由自己來定了。
題意:
百度。
思路:
樹狀陣列是用來標記的!值->區間點!
因為這裡值重複是算的,所有樹狀陣列存的是區間上該位置的個數。
0:插入則插入。
1:if(!(sum[x]-sum[x-1])) puts("NO...");
2:我們知道a(包括a)之前有多少個數x,求第k大的數,也就是求在樹狀陣列中第x+k大的數。
sum[ans]=x+k。這個可以直接二分查詢。
---
哦,還可以線段樹,還是一樣的,值->區間點,點所存的值自己定,這裡也就是個數,差不多。但是這個查詢第k大的數的位置,麻煩了。
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> PII; const int N=1e5+10; int c[N],m; int lowbit(int x) { return x&(-x); } void add(int x,int val) { while(x<=100000) { c[x]+=val; x+=lowbit(x); } } int sum(int x) { int ans=0; while(x>0) { ans+=c[x]; x-=lowbit(x); } return ans; } int main() { while(~scanf("%d",&m)) { int x; int a,k; memset(c,0,sizeof(c)); while(m--) { scanf("%d",&x); if(x==0) { scanf("%d",&a); add(a,1); } else if(x==1) { scanf("%d",&a); if(sum(a)-sum(a-1)==0) puts("No Elment!"); else add(a,-1); } else { scanf("%d%d",&a,&k); int p=sum(a)+k; int left=1,right=100000; while(left<right) { int mid=left+(right-left)/2; if(sum(mid)>=p) right=mid; else left=mid+1; } if(sum(left)>=p) printf("%d\n",left); else puts("Not Find!"); } } } return 0; }