標籤:bestcoder acm algorithm
Rikka with sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 378 Accepted Submission(s): 75
Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:
Yuta have a sequence. Because the sequence is very self-willed(RenXing), at first the sequence is empty. And then Yuta do n operations on this sequence, each operation is either of these two types:
1.Add a number w into each gap of the sequence. For example if w=3 and the sequence before is “2 4”, it will be changed to “3 2 3 4 3”.
**after the first operation of the first type, there is only one number in the sequence**
2.Query the kth small number in the subsequence [L,R]. For example if k=2, L=2, R=4 and the sequence is “3 2 3 4 2”, the answer will be 3.
Yuta wants Rikka to tell him the answer of each query.
It is too difficult for Rikka. Can you help her?
InputThe first line contains one number n(n≤100000). Each of the following n lines describes an operation: if it is “1 w” it will be the first type. Otherwise if it is “2 L R k”, it will be the second type. (1≤w≤109,L≤R≤1018)
R will not be larger than the length of the sequence
OutputFor each query operation, output one number – the answer.
Sample Input
61 31 12 2 3 21 22 3 5 22 1 4 4
Sample Output
323
官方題解:
這題看起來一副非常厲害的樣子。。其實是大水題。對於一個詢問,考慮這個詢問前第i次修改操作,那麼這次修改操作出現在序列中第一個位置是2i?1。然後在詢問範圍內最多隻有60個數,暴力大法好就好了,時間複雜度O(nlogR),R是詢問的最大下標。
ps:自己類比一下就會發現,對第i個要插入的數,在整個區間插入入的數的數量是2^(i-1)個,並且在[1,R]內也滿足,後一個數插入的數的數量一定是前一個插入數的2倍,或2倍+1,知道這個後,[L,R]=[1,R]-[1,L-1],於是sum[i]+=v*(x+1)/2;在[1,R]中v為1,在[1,L-1]中v為-1,此時的i的順序與插入順序相反。
代碼:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=110000;int a[maxn],b[maxn];long long sum[maxn];int len=69;void digt(long long x,int v){ int i=0; while(x) { sum[i]+=v*(x+1)/2; x=x/2; i++; }}bool cmp(int x,int y){ return a[len-x]<a[len-y];}int main(){ int t,op; scanf("%d",&t); long long l,r,k,ans; while(t--) { scanf("%d",&op); if(op==1) { scanf("%d",&a[++len]); } else { scanf("%I64d%I64d%I64d",&l,&r,&k); for(int i=0;i<=100;i++) sum[i]=0; digt(r,1); digt(l-1,-1); for(int i=0;i<=69;i++) b[i]=i; sort(b,b+70,cmp); ans=0; for(int i=0;i<70;i++) { // cout<<i<<" "<<sum[b[i]]<<endl; if(ans+sum[b[i]]>=k) { printf("%d\n",a[len-b[i]]); break; } else { ans+=sum[b[i]]; } } } } return 0;}
hdu 5204 Rikka with sequence(BestCoder Round #37)