hdu2852(權值樹狀數組)

Problem Description For the k-th number, we all should be very
familiar with it. Of course,to kiki it is also simple. Now Kiki meets
a very similar problem, kiki wants to design a container, the
container is to support the three operations.

Push: Push a given element e to container

Pop: Pop element of a given e from container

Query: Given two elements a and k, query the kth larger number which
greater than a in container;

Although Kiki is very intelligent, she can not think of how to do it,
can you help her to solve this problem?

Input Input some groups of test data ,each test data the first number
is an integer m (1 <= m <100000), means that the number of operation
to do. The next m lines, each line will be an integer p at the
beginning, p which has three values: If p is 0, then there will be an
integer e (0 <e <100000), means press element e into Container.

If p is 1, then there will be an integer e (0 <e <100000), indicated
that delete the element e from the container

If p is 2, then there will be two integers a and k (0 <a <100000, 0 <k
<10000),means the inquiries, the element is greater than a, and the
k-th larger number.

Output For each deletion, if you want to delete the element which does
not exist, the output “No Elment!”. For each query, output the
suitable answers in line .if the number does not exist, the output
“Not Find!”.

Sample Input
5 0 5 1 2 0 6 2 3 2 2 8 1 7 0 2 0 2 0 4 2 1 1 2 1 2 2 1 3 2 1 4

Sample Output
No Elment!
6
Not Find!
2
2
4
Not Find!

題目大意:
一個容器裏面有三種操作
1 向集合中增加一個數
2 刪除集合中的一個數
3 查詢集合中第k個比a大的數

思路:
用權值樹狀數組或者權值線段樹維護,題目的數據範圍也比較小,不需要離散也不需要longlong
難點就是在於查詢,所以用到二分的思想,樹狀數組維護的是前綴和(前面數字出現過的次數),求getsum(mid),與第k大相比較,k大於getsum(mid)則說明第k大在左半邊區間,否則在右半邊區間。最後就是,查詢第k個比a大的數其實就是 查詢[1,n]區間內的第getsum(k)+a 個數。
明顯,用樹狀數組 比 用線段樹維護要簡單點


代碼:
查詢時如果我不用maxn-1就wa,不知道爲什麼

#include <bits/stdc++.h>

using namespace std;

const int maxn=100000+50;
typedef long long ll;
int t,n,q,e,l,k,x;
ll tree[maxn];
ll a[maxn];
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int k)
{
    while(x<maxn)
    {
        tree[x]+=k;
        x+=lowbit(x);
    }
}
int getsum(int x)
{
    int res=0;
    while(x>0)
    {
        res+=tree[x];
        x-=lowbit(x);
    }
    return res;
}
int query(int x,int l,int r)//查詢第x大的數
{
    if(l==r) return l;
    int mid=(l+r)/2;
//    printf(" x=%d %d %d %d\n",x,l,r,getsum(mid));
    if(x>getsum(mid))
    {
        query(x,mid+1,r);
    }
    else
    {
        query(x,l,mid);
    }
}
int main()
{
    while(scanf("%d",&q)==1)
    {
        //init
        memset(a,0,sizeof a);
        memset(tree,0,sizeof tree);
        while(q--)
        {
           scanf("%d",&e);
           if(e==0)
           {
               scanf("%d",&x);
               a[x]++;
               update(x,1);
           }
           else if(e==1)
           {
               scanf("%d",&x);
               if(a[x]==0)
                    printf("No Elment!\n");
               else
                    a[x]--,update(x,-1);
           }
           else
           {
               scanf("%d%d",&l,&k);
               int num=getsum(l);
               if(num+k> getsum(maxn-1)) printf("Not Find!\n");
               else
               {
                   int res=query(k+num,1,maxn-1);
                   printf("%d\n",res);
               }
           }
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章