hdu 5.3.1 2852 KiKi's K-Number

好像線段樹和樹狀數組都可以解……不過困死了,先貼樹狀數組的吧……我也不知道爲什麼我一時腦殘居然選了一個新的解法

KiKi's K-Number

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 44 Accepted Submission(s): 22
 
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!
 




樹狀數組是一個可以很高效的進行區間統計的數據結構。在思想上類似於線段樹,比線段樹節省空間,編程複雜度比線段樹低,但適用範圍比線段樹小。

#include <iostream>
#include <cstring>
#define maxn 300003
#define maxm 100002
using namespace std;

int a[maxm];
int c[maxn];

int lowbit(int x)//find the max power of two that x can be divided
{return -x&x;}

void p(int pos,int num)
{
    while(pos<maxn)
    {
        c[pos]+=num;
        pos+=lowbit(pos);//find the node higher than this
    }
}

int sum(int end)
{
    int sum=0;
    while(end>0)
    {
        sum+=c[end];
        end-=lowbit(end);//find the node smaller than this
    }
    return sum;
}

int query(int n,int k)
{
    int mid,low,high;
    int i,j,t;
    if(sum(maxm)-sum(n)<k)
        return 0;
    i=sum(n);//how many number smaller than or equal to a
    low=n;
    high=maxm;
    while(low<=high)
    {
        mid=(low+high)>>1;
        t=sum(mid);//how many number smaller than or equal to mid
        if(a[mid] && t-a[mid]<k+i && t>=k+i)
        //have number mid   
            break;
        else if(t<k+i)
            low =mid+1;
        else
            high=mid-1;
    }
    printf("%d\n",mid);
    return 1;
}
        
    
    
    
    

int main()

{
    int t;
    while(cin>>t)
    {
         memset(c,0,sizeof(c));
         memset(a,0,sizeof(a));
         while(t--)
         {
             int s;
             int n,m;
             scanf("%d",&s);
             if(!s)//s==0
             {
                 scanf("%d",&n);
                 p(n,1);
                 a[n]++;
             }
             else if(s==1)
             {
                  scanf("%d",&n);
                  if(a[n]<=0)
                      printf("No Elment!\n");
                  else
                  {
                      p(n,-1);
                      a[n]--;
                  }
             }
             else
             {
                 scanf("%d%d",&n,&m);
                 if(!query(n,m))
                     printf("Not Find!\n");
             }
         }
    }

                       
    return 0;
}

解裏面的lowbit很有趣,把數組拗成了一棵樹……

總體來說這個做法我只能到看懂的程度……

順便吐槽一下你妹element題目居然拼錯了……偶爾沒直接複製不用就這麼整我吧暈……

困死了……

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