HDU - 4217 Data Structure? 線段樹
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個數,一共有 k 次操作,每次取出第 ki 小的數。問所有取出數字之和。
題解:線段樹維護下區間還有多少數,更新到節點即可
#include<iostream> #include<cstdio> using namespace std; const int N=270000; typedef long long ll; struct node{ int l,r,sum; }tree[N<<2]; int n,k; void build(int l,int r,int cur) { tree[cur].l=l; tree[cur].r=r; tree[cur].sum=r-l+1; if(l==r)return; int mid=(r+l)>>1; build(l,mid,cur<<1); build(mid+1,r,cur<<1|1); } int query(int cur,int pos) { if(tree[cur].l==tree[cur].r) { tree[cur].sum=0; return tree[cur].l; } int res; if(tree[cur<<1].sum>=pos) res=query(cur<<1,pos); else { res=query(cur<<1|1,pos-tree[cur<<1].sum); } tree[cur].sum=tree[cur<<1].sum+tree[cur<<1|1].sum; return res; } int main() { int T,nn=1; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&k); build(1,n,1); ll ans=0; int x; for(int i=1;i<=k;i++) { scanf("%d",&x); ans+=query(1,x); } printf("Case %d: %lld\n",nn++,ans); } return 0; }