Data Structure?
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2133 Accepted Submission(s): 682
Problem DescriptionData 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.
InputThe 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
OutputFor each test case, output the case number first, then the sum.
Sample Input
23 21 110 33 9 1
Sample Output
Case 1: 3Case 2: 14
Code:
題意是每次取走第k個數,問最後共取走多大的數
在結構體體裡用一個變數表示這一段數位個數,取走一個就更新,-1
取數的時候如果k>左子樹的len,那麼應該轉向右子樹尋找, 否則就在左子樹尋找
知道找到一個區間lside==rside, 即為要取的數
尋找過程中就--len,順便更新
HDOJ不能用long long, 用__int64來表示大數, %I64d輸出
#include<stdio.h>#define M 300000struct node{ int l,r; int len;}tree[M*4];void build(int p,int l,int r){ tree[p].l = l; tree[p].r = r; tree[p].len = r-l+1; if(l==r) return; int mid = (l+r)>>1; int next = p<<1; build(next,l,mid); build(next+1,mid+1,r);}__int64 take(int p,int n){ tree[p].len--; if(tree[p].l == tree[p].r){ return tree[p].l; } int next = p<<1; if(tree[next].len < n) take(next+1,n-tree[next].len); else take(next,n); }int main(){ int t,ca,n,k,i,j; __int64 sum; scanf("%d",&t); for(ca=1;ca<=t;ca++) { scanf("%d%d",&n,&k); build(1,1,n); sum = 0; for(j=0;j<k;j++) { scanf("%d",&n); sum += take(1,n); } printf("Case %d: %I64d\n",ca,sum); } return 0;}