Data Structure? HDU - 4217(树状数组+二分)

Data structure is one of the basic skills for Computer Science students, which is a particular way of storing and organizing data in a computer so that it can be used efficiently. Today let me introduce a data-structure-like problem for you.
Original, there are N numbers, namely 1, 2, 3…N. Each round, iSea find out the Ki-th smallest number and take it away, your task is reporting him the total sum of the numbers he has taken away.
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case includes two integers N, K, K indicates the round numbers. Then a line with K numbers following, indicating in i (1-based) round, iSea take away the Ki-th smallest away.

Technical Specification
1. 1 <= T <= 128
2. 1 <= K <= N <= 262 144
3. 1 <= Ki <= N - i + 1
Output
For each test case, output the case number first, then the sum.
Sample Input
2
3 2
1 1
10 3
3 9 1
Sample Output
Case 1: 3
Case 2: 14

思路:因为是1到n这个性质要利用起来,n的范围不大,可以用数组数组来查询,如果某个数置1,代表这个数被拿走了,二分去找第k小,因为有单调性,难度还行吧。
代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 262154
using namespace std;
int c[maxn];
int n,q;
int change(int x,int p)
{
    for(;x<=n;x+=x&(-x))c[x]+=p;
}
int query(int x)
{
    int ans=0;
    for(;x;x-=x&-x)ans+=c[x];
    return ans;
}
int getPos(int k)
{
    int l=0,r=n-1;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        int now=mid-query(mid);
        if(now>=k)
            r=mid-1;
        else
            l=mid+1;
    }
    return l;
}
int main()
{
    int t;
    cin>>t;
    int cal=1;
    while(t--)
    {
       cin>>n>>q;
       memset(c,0,sizeof(c));
       long long ans=0;
       int x;
       for(int i=0;i<q;i++)
       {
           scanf("%d",&x);
           int num=getPos(x);
           ans+=num;
           change(num,1);
       }
       printf("Case %d: %lld\n",cal++,ans);
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/coldfresh/article/details/81107395