Problem Description
Jimmy wants to make a special necklace for his girlfriend. He bought many beads with various sizes, and no two beads are with the same size. Jimmy can’t remember all the details about the beads, for the necklace is so long. So he turns to you for help.
Initially, there is no bead at all, that is, there is an empty chain. Jimmy always sticks the new bead to the right of the chain, to make the chain longer and longer. We number the leftmost bead as Position 1, and the bead to its right as Position 2, and so on. Jimmy usually asks questions about the beads’ positions, size ranks and actual sizes. Specifically speaking, there are 4 kinds of operations you should process:
Insert x
Put a bead with size x to the right of the chain (0 < x < 231, and x is different from all the sizes of beads currently in the chain)
Query_1 s t k
Query the k-th smallest bead between position s and t, inclusive. You can assume 1 <= s <= t <= L, (L is the length of the current chain), and 1 <= k <= min (100, t-s+1)
Query_2 x
Query the rank of the bead with size x, if we sort all the current beads by ascent order of sizes. The result should between 1 and L (L is the length of the current chain)
Query_3 k
Query the size of the k-th smallest bead currently (1 <= k <= L, L is the length of the current chain)
Input
There are several test cases in the input. The first line for each test case is an integer N, indicating the number of operations. Then N lines follow, each line contains one operation, as described above.
You can assume the amount of “Insert” operation is no more than 100000, and the amounts of “Query_1”, “Query_2” and “Query_3” are all less than 35000.
There are several test cases in the input. The first line for each test case is an integer N, indicating the number of operations. Then N lines follow, each line contains one operation, as described above.
You can assume the amount of “Insert” operation is no more than 100000, and the amounts of “Query_1”, “Query_2” and “Query_3” are all less than 35000.Query the rank of the bead with size x, if we sort all the current beads by ascent order of sizes. The result should between 1 and L (L is the length of the current chain)
Query_3 k
Query the size of the k-th smallest bead currently (1 <= k <= L, L is the length of the current chain)
Output
Output 4 lines for each test case. The first line is “Case T:”, where T is the id of the case. The next 3 lines indicate the sum of results for Query_1, Query_2 and Query_3, respectively.
Sample Input
10
Insert 1
Insert 4
Insert 2
Insert 5
Insert 6
Query_1 1 5 5
Query_1 2 3 2
Query_2 4
Query_3 3
Query_3 1
Sample Output
Case 1:
10
3
5
HintThe answers for the 5 queries are 6, 4, 3, 4, 1, respectively.
就算主席树数在线处理的,我们依旧可以离线做,一开始没想到,一直想着新进来一个数怎么回到以前状态去更新,但那个代码不仅麻烦而且估计会t,而且,hdu这道题最坑的地方是,我这个电脑看那道题目的数据范围是231!!然后一直wa,仔细想了想才明白应该是2^31!,所以就要用到离散化了,再开一个vector,那么这道题就相当于一个区间查询罢了,至于剩下两个询问直接用vector做就好了。还是太年轻了QAQ
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+5;
int ls[maxn*25],rs[maxn*25],rt[maxn],sum[maxn*25];
int cnt;
void update(int l,int r,int root,int last,int val)
{
ls[root]=ls[last];
rs[root]=rs[last];
sum[root]=sum[last]+1;
if(l==r)
return ;
int mid=l+r>>1;
if(mid>=val)
update(l,mid,ls[root]=++cnt,ls[last],val);
else
update(mid+1,r,rs[root]=++cnt,rs[last],val);
}
int query(int l,int r,int root,int last,int val)
{
if(l==r)
return l;
int all=sum[ls[root]]-sum[ls[last]];
int mid=l+r>>1;
if(all>=val)
return query(l,mid,ls[root],ls[last],val);
else
return query(mid+1,r,rs[root],rs[last],val-all);
}
int a[3*maxn],b[3*maxn],op[3*maxn],v[3*maxn],le[3*maxn],rig[3*maxn];
vector<int>vec;
int main()
{
int n;
int cas=0;
while(~scanf("%d",&n))
{
char s[10];
int val,l,r;
int now=0;
cnt=0;
memset(sum,0,sizeof(sum));
ll ans[5]={0};
int len=0;
vec.clear();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
if(s[0]=='I')
{
op[i]=1;
scanf("%d",&v[i]);
len++;
a[len]=b[len]=v[i];
}
else if(s[6]=='1')
scanf("%d%d%d",&le[i],&rig[i],&v[i]),op[i]=2;
else if(s[6]=='2')
scanf("%d",&v[i]),op[i]=3;
else
scanf("%d",&v[i]),op[i]=4;
}
sort(b+1,b+1+len);
for(int i=1;i<=len;i++)
a[i]=lower_bound(b+1,b+1+len,a[i])-b;
for(int i=1;i<=len;i++)
update(1,len,rt[i]=++cnt,rt[i-1],a[i]);
for(int i=1;i<=n;i++)
{
if(op[i]==1)
vec.insert(lower_bound(vec.begin(),vec.end(),v[i]),v[i]);
else if(op[i]==2)
ans[1]+=(ll)b[query(1,len,rt[rig[i]],rt[le[i]-1],v[i])];
else if(op[i]==3)
ans[2]+=(ll)(lower_bound(vec.begin(),vec.end(),v[i])-vec.begin())+1;
else
ans[3]+=(ll)vec[v[i]-1];
}
printf("Case %d:\n",++cas);
for(int i=1;i<=3;i++)
printf("%lld\n",ans[i]);
}
return 0;
}