zoukankan      html  css  js  c++  java
  • HDU 3727 Jewel 可持久化线段树

    Jewel



    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
    Hint
    The answers for the 5 queries are 6, 4, 3, 4, 1, respectively.
     

    题意:

      

     这个是需要离线离散化的,题目中 231 意思是2^31.................

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18;
    const double Pi = acos(-1.0);
    const int N = 2e5+10, M = 2e5+35000+11, mod = 1e9+7, inf = 0x3fffffff;
    
    struct Query{int x,s,t,k;}Q[M];
    int l[N*10],r[N*10],v[N*10],san[N],cnt,num,root[N],sz,c,n;
    LL ans1,ans2,ans3;
    char ch[M][7];
    void init() {
            cnt = 0;
            root[0] = 0;
            sz = 0;
            num = 1;
            ans1 = 0;
            ans2 = 0;
            ans3 = 0;
            memset(l,0,sizeof(l));
            memset(r,0,sizeof(r));
            memset(v,0,sizeof(v));
    }
    
    void update(int &k,int ll,int rr,int x) {
            ++sz;
            l[sz] = l[k];
            r[sz] = r[k];
            v[sz] = v[k] + 1;
            k = sz;
            if(ll == rr) return ;
            if(x <= mid) update(l[k],ll,mid,x);
            else update(r[k],mid+1,rr,x);
    }
    int query_1(int x,int y,int ll,int rr,int k) {
            if(ll == rr) return ll;
            int ret = v[l[y]] - v[l[x]];
            if(ret >= k) return query_1(l[x],l[y],ll,mid,k);
            else return query_1(r[x],r[y],mid+1,rr,k - ret);
    }
    int query_3(int &k,int ll,int rr,int x) {
            if(ll == rr) return ll;
            int ret = v[l[k]];
            if(ret >= x) return query_3(l[k],ll,mid,x);
            else return query_3(r[k],mid+1,rr,x-ret);
    }
    int query_2(int &k,int ll,int rr,int x) {
            if(ll == rr) return 1;
            if(x <= mid) return query_2(l[k],ll,mid,x);
            else return v[l[k]] + query_2(r[k],mid+1,rr,x);
    }
    int haxi(int x) {return lower_bound(san+1,san+c+1,x) - san;}
    int main() {
            int cas = 1;
            while(scanf("%d",&n)!=EOF) {
                init();
                for(int i = 1; i <= n; ++i) {
                    scanf("%s",ch[i]);
                    if(ch[i][0] == 'I') {
                        scanf("%d",&Q[i].x);
                        san[++cnt] = Q[i].x;
                    } else if(ch[i][0] == 'Q') {
                        if(ch[i][6] == '1') {
                            scanf("%d%d%d",&Q[i].s,&Q[i].t,&Q[i].k);
                        } else if(ch[i][6] == '2'){
                            scanf("%d",&Q[i].x);
                            san[++cnt] = Q[i].x;
                        } else if(ch[i][6] == '3') {
                            scanf("%d",&Q[i].k);
                        }
                    }
                }
                sort(san+1,san+cnt+1);
                c = unique(san+1,san+cnt+1) - san - 1;
                for(int i = 1; i <= n; ++i) {
                    if(ch[i][0] == 'I') {
                        int fx = haxi(Q[i].x);
                        update(root[num] = root[num-1],1,c,fx);
                        ++num;
                    } else {
                        if(ch[i][6] == '1') {
                            ans1 += san[query_1(root[Q[i].s-1],root[Q[i].t],1,c,Q[i].k)];
                        } else if(ch[i][6] == '2') {
                            int fx = haxi(Q[i].x);
                            ans2 += query_2(root[num-1],1,c,fx);
                        } else if(ch[i][6] == '3') {
                            ans3 += san[query_3(root[num-1],1,c,Q[i].k)];
                        }
                    }
                }
                printf("Case %d:
    ",cas++);
                printf("%I64d
    %I64d
    %I64d
    ",ans1,ans2,ans3);
            }
            return 0;
    }
  • 相关阅读:
    如何使用Python创建可视化对象
    Power Query中如何解析累积总计
    如何快速复制度量值?
    如何使用文本字段进行条件格式设置
    Power BI 3-4月功能更新培训合集
    2019微软Power BI 每月功能更新系列——Power BI 4月版本功能完整解读
    送你一份堆积柱形图小点心,请收下~
    命令行编译带外部包依赖的java源文件 [以JDBC MySQL8为例]
    JavaScript (JS)常用方法
    JDK8过渡到JDK11
  • 原文地址:https://www.cnblogs.com/zxhl/p/5893587.html
Copyright © 2011-2022 走看看