HDU3727 Jewel

来源:互联网 发布:服装设计需要的软件 编辑:程序博客网 时间:2024/06/05 06:56

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 longint 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;}