[hdu4217]Data Structure?

Time Limit: 10000/5000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)

Problem Description
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 NN numbers, namely 1,2,3...N1, 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 TT, indicating the number of test cases.
Each test case includes two integers NN,K,KK, K indicates the round numbers. Then a line with KK numbers following, indicating in ii (1-based) round, iSea take away the KiKi-th smallest away.

Technical Specification

1 <= T <= 128
1 <= K <= N <= 262 144
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

題意:
給定nn個數字11nn,將他們存在集合中,有KK組詢問,每次詢問一個數字kiki,將集合中的第kiki小的數字加到ans上,並將其從集合中刪去,問KK次操作之後,ans爲多少。

題解:
權值線段樹,每次查詢前綴和爲ki+1ki+1的位置,並將其設爲0即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct seg{
    int l,r,w;
}tr[1000004];
int n;
ll ans;
void build(int k,int l,int r){
    tr[k].l=l;tr[k].r=r;
    if(l==r){
        tr[k].w=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    tr[k].w=tr[k<<1].w+tr[k<<1|1].w;
}
int work(int k,int x){
    int l=tr[k].l,r=tr[k].r;
    if(l==r){
        ans+=l;
        tr[k].w=0;
        return l;
    }
    int mid=(l+r)>>1;
    if(tr[k<<1].w>=x)work(k<<1,x);
    else work(k<<1|1,x-tr[k<<1].w);
    tr[k].w=tr[k<<1].w+tr[k<<1|1].w;
}
int w33ha(int CASE){
    scanf("%d",&n);
    build(1,1,n);
    ans=0;
    int K;scanf("%d",&K);
    for(int i=1;i<=K;i++){
        int x;scanf("%d",&x);
        work(1,x);
    }
    printf("Case %d: %lld\n",CASE,ans);
    return 0;
}

int main(){
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)w33ha(i);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章