您的位置:首页 > 其它

HDU3727 Jewel

2017-07-13 09:36 169 查看

Jewel

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

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

/*
STL中unique函数是一个去重函数,
unique的功能是去除相邻的重复元素(只保留一个),
其实它并不真正把重复的元素删除,是把重复的元素移
到后面去了,然后依然保存到了原数组中,然后 返
回去重后最后一个元素的地址,因为unique去除的是
相邻的重复元素,
所以一般用之前都会要排一下序。
*/
/*
函数名:strcmp
功能:STL自带的字符串比较
用法int strcmp(char *str1,char *str2)
str1>str2 返回值>0  str1==str2 返回值等于0
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<vector>
using namespace std;
#define maxn 100005
#define INF 1e9+7
#define LL long long
int cnt[maxn*20],ls[maxn*20],rs[maxn*20],T[maxn];
int a[maxn],num[maxn];
char op[maxn*2][16];
int L[maxn*20],R[maxn*20],K[maxn*20];
int tot;
vector<int> vec;
void Build(int l,int r,int &cur){
cur= ++tot;cnt[cur]=0;
if(l==r) return;
int mid=(l+r)>>1;
Build(l,mid,ls[cur]);
Build(mid+1,r,rs[cur]);
}
void Insert(int pre,int p,int l,int r,int &cur){
cur= ++tot;
ls[cur]=ls[pre];rs[cur]=rs[pre];
cnt[cur]=cnt[pre]+1;
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) Insert(ls[pre],p,l,mid,ls[cur]);
else Insert(rs[pre],p,mid+1,r,rs[cur]);
}
int query(int ss,int tt,int l,int r,int k){
if(l==r) return r;
int sum=cnt[ls[tt]]-cnt[ls[ss]];
int mid=(l+r)>>1;
if(sum>=k) return query(ls[ss],ls[tt],l,mid,k);
else return query(rs[ss],rs[tt],mid+1,r,k-sum);
}
int main(){
int m,kcase=0;
while(scanf("%d",&m)!=EOF){
memset(cnt,0,sizeof cnt );
int len=0,n;
LL q1=0,q2=0,q3=0;
vec.clear();
for(int i=0;i<m;i++){
scanf("%s%d",op[i],&L[i]);
if(!strcmp(op[i],"Insert")){
++len;
num[len]=a[len]=L[i];
}
else if(!strcmp(op[i],"Query_1"))
scanf("%d%d",&R[i],&K[i]);
}
sort(a+1,a+len+1);
n=len;
len=unique(a+1,a+len+1)-a-1;
for(int i=1;i<=n;i++)
num[i]=lower_bound(a+1,a+len+1,num[i])-a;
tot=0;
Build(1,len,T[0]);//建立第0棵线段树(建空树)
for(int i=1;i<=n;i++)
Insert(T[i-1],num[i],1,len,T[i]);//(建立后续的线段树,每一棵都借用前一棵的信息)
for(int i=0;i<m;i++){
if(!strcmp(op[i],"Insert"))
vec.insert(lower_bound(vec.begin(),vec.end(),L[i]),L[i]);
else if(!strcmp(op[i],"Query_1"))
q1+=a[query(T[L[i]-1],T[R[i]],1,len,K[i])];
else if(!strcmp(op[i],"Query_2"))
q2+=lower_bound(vec.begin(),vec.end(),L[i])-vec.begin()+1;
else q3+=vec[L[i]-1];
}
printf("Case %d:\n",++kcase);
printf("%I64d\n%I64d\n%I64d\n",q1,q2,q3);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  主席树