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) 

InputThere 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) 

OutputOutput 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.

题解:可持续化线段树的模板题

AC代码为:

/*
有四种操作
1、在序列最优插入一个数字(该数字从没出现过)
2、询问序列内某区间第k小值
3、询问当前序列内数字x是第几小的(x一定在序列中)
4、询问当前序列内第k小的值
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;  
int tot,rt[N]; 
char s[10];
vector<int> v;  
struct data  
{  
    int id;  
    int l,r,x;  
}data[N*2];  
   
inline int getid(int x) {return lower_bound(v.begin(),v.end(),x) - v.begin() + 1;}  
  
void input(int n)  
{  
    char s[10];
    int x;  
    for(int i=0;i<n;i++)  
    {  
        scanf("%s",s);  
        if(s[0]=='I')  
        {  
            scanf("%d",&x); 
            data[i].id = 0;  
            data[i].x = x;  
            v.push_back(x);  
        }  
        else if(s[6]=='1')  
        {  
            int a,b,c;  
            scanf("%d%d%d",&a,&b,&c);  
            data[i].id = 1;  
            data[i].l = a, data[i].r = b, data[i].x = c;  
        }  
        else if(s[6]=='2')  
        {  
            scanf("%d",&x);  
            data[i].id = 2;  
            data[i].x = x;  
        }  
        else  
        {  
            scanf("%d",&x);  
            data[i].id = 3;  
            data[i].x = x;  
        }  
    }  
}    
struct node  
{  
    int l,r,sum;  
}tree[N*24];   
    
inline void build(int l,int r,int &x) //1~v.size() 
{  
    x = ++tot;  
    tree[x].sum = 0;  
    if(l==r) return;  
    int m = (l+r) >> 1;  
    build(l,m,tree[x].l);  
    build(m+1,r,tree[x].r);  
}  
  
inline void update(int l,int r,int &x,int y,int k)  
{  
   tree[++tot] = tree[y], tree[tot].sum++,x=tot;  
    if(l==r) return;  
    int m = (l+r) >> 1;  
    if(k<=m) update(l,m,tree[x].l,tree[y].l,k);  
    else update(m+1,r,tree[x].r,tree[y].r,k);  
}  
  
inline int query1(int l,int r,int y,int x,int k)  //查找区间第k小的数  
{  
    if(l==r) return l;  
    int mid = (l+r) >> 1;  
    int sum = tree[tree[x].l].sum - tree[tree[y].l].sum;  
    if(k<=sum) return query1(l,mid,tree[y].l,tree[x].l,k);  
    else return query1(mid+1,r,tree[y].r,tree[x].r,k-sum);  
}  
  
inline int query2(int l,int r,int x,int k) //在当前序列中,输出X是第几小的数。  
{  
    if(l==r) return 1;  
    int mid = (l+r) >> 1;  
    if(k<=mid) return query2(l,mid,tree[x].l,k);  
    else  
    {  
        int sum = tree[tree[x].l].sum;  
        return sum += query2(mid+1,r,tree[x].r,k);  
    }  
}  
  
inline int query3(int l,int r,int x,int k) //找到当前序列中第X小的数是几  
{  
    if(l==r) return l;  
    int mid = (l+r) >> 1;  
    int sum = tree[tree[x].l].sum;  
    if(sum>=k) return query3(l,mid,tree[x].l,k);  
    else return query3(mid+1,r,tree[x].r,k-sum);  
}      
int main()  
{   
    ios::sync_with_stdio(0);  
    cin.tie(0); 
    int n;  
    int cas = 1;  
    while(~scanf("%d",&n))  
    {  
        v.clear();  
        tot = 0;  
        LL ans1 = 0, ans2 = 0, ans3 = 0;  
        input(n);  
        sort(v.begin(),v.end());  
        v.erase(unique(v.begin(),v.end()),v.end());  
        int cnt = v.size();  
        build(1,cnt,rt[0]);  
        int now = 1;  
        for(int i=0;i<n;i++)  
        {  
            if(data[i].id==0)  
            {  
                update(1,cnt,rt[now],rt[now-1],getid(data[i].x));  
                now++;  
            }  
            else if(data[i].id==1)  
            {  
                int l = data[i].l, r = data[i].r, x = data[i].x;  
                ans1 += v[query1(1,cnt,rt[l-1],rt[r],x)-1];  
            }  
            else if(data[i].id==2) ans2+=query2(1,cnt,rt[now-1],getid(data[i].x));               
            else ans3+=v[query3(1,cnt,rt[now-1],data[i].x)-1];      
        }    
        printf("Case %d:\n%I64d\n%I64d\n%I64d\n",cas++,ans1,ans2,ans3);  
    }  
    return 0;  
}

HDU-3727 Jewel的更多相关文章

  1. hdu 3727 Jewel (可持久化线段树+bit)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=3727 题意: 对一段序列进行四种操作: Insert x :在序列尾部插入一个x: Query_1 s ...

  2. HDU 3727 Jewel 可持久化线段树

    Jewel Problem Description   Jimmy wants to make a special necklace for his girlfriend. He bought man ...

  3. HDU 3727 Jewel 主席树

    题意: 一开始有一个空序列,然后有下面四种操作: Insert x在序列尾部加入一个值为\(x\)的元素,而且保证序列中每个元素都互不相同. Query_1 s t k查询区间\([s,t]\)中第\ ...

  4. 【HDOJ】3727 Jewel

    静态区间第K大值.主席树和划分树都可解. /* 3727 */ #include <iostream> #include <sstream> #include <stri ...

  5. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  7. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  8. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  9. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  10. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

随机推荐

  1. win7/win10系列的office安装与激活

    Windows系列电脑安装office傻瓜式教程 一.    下载与安装 下载 (1).所需工具:迅雷 下载链接:http://xl9.xunlei.com/ 显示界面如下,点击“立即下载”即可,然后 ...

  2. T-SQL, Part II: IMAGE/TEXT Insert

    To insert data to IMAGE/TEXT (both keywords are recommend to replace with nvarbinary(MAX)/nvarchar(M ...

  3. springboot配置springMVC

    /** * @ClassName MvcConfigure * @Description SpringMVC配置 * @Author JAGNG * @Date 2019/10/28 10:23 ** ...

  4. Ubuntu 18 安装搜狗输入法

    Ubuntu 18 安装搜狗输入法: 1. 搜狗输入法官网下载对应的Linux输入法 2. 双击 刚刚下载好的 deb 文件 3. 点击 install(安装) 4. 在 settings(系统设置) ...

  5. hdu 1556 Color the ball (树状数组)

    Color the ballTime Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  6. JS的原型和继承

    __proto__除null和undefined,JS中的所有数据类型都有这个属性: 它表示当我们访问一个对象的某个属性时,如果该对象自身不存在该属性, 就从它的__proto__属性上继续查找,以此 ...

  7. 学习记录:《C++设计模式——李建忠主讲》4.“单一职责”模式

    单一职责模式:在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式:装饰模式(Decorator).桥 ...

  8. BloomFilter在Hudi中的应用

    Bloom Filter在Hudi中的应用 介绍 Bloom Filter可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,主要缺点是存在一定的误判率:当其判断元 ...

  9. 使用runc直接运行容器

    组件containerd负责集群节点上容器的生命周期管理,并向上为docker daemon提供gRPC接口,containerd依靠runC去创建容器进程.而在容器启动之后,runC进程会退出. 可 ...

  10. nslookup命令查找域名

    了解 DNS 域名服务 熟悉使用 nslookup 查找 DNS 服务器上登记的域名,记录几次查询的结果, 及服务器的 ip. 1. 某个子域下的一部分主机的名字- IP 地址对应关系,如 flame ...