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

题意:

输入n,再输入n个操作,操作有四种

0,  Insert X:插入x到序列末尾 
 1,  query_1 L R X:在当前序列中的[l,r]区间找第x小的数。 
 2,  query_2 X:在当前序列中,输出X是第几小的数。 
 3,  query_3 X:找到当前序列中第X小的数是几。 
然后输出的是3种query的和。

思路:

操作1和操作3是查询区间第k小,主席树。

操作2是求排名,用树状数组或者二分。

在线转化为离线。

求Kth的主席树的模板见我之前写的:http://www.cnblogs.com/hua-dong/p/7931778.html

操作2为二分的代码:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=;
int a[maxn],b[maxn],Innum,n;//a是位置,b是值。Innum是输入的个数,即
int cnt,ql,qr,Case=;
long long sum1,sum2,sum3;
struct questions
{
int opt;//0,1,2,3
int x,y,k;
}Qst[maxn<<];
struct PLTree
{
int ch[maxn * ][],sum[maxn * ],rt[maxn];
void build(int& now,int l,int r)
{
now = ++ cnt;
sum[now] = ;
if(l == r) return ;
int Mid = (l + r)>>;
build(ch[now][],l,Mid);
build(ch[now][],Mid + ,r);
}
void insert(int& now,int last,int l,int r,int pos)
{
now = ++ cnt;
ch[now][]=ch[last][];
ch[now][]=ch[last][];
sum[now] = sum[last] + ;
if(l == r) return ;
int Mid = (l+r) >> ;
if(pos <= Mid) insert(ch[now][],ch[last][],l,Mid,pos);
else insert(ch[now][],ch[last][],Mid + ,r,pos);
}
int query(int ss,int tt,int l,int r,int k)
{
if(l == r) return l;
int Mid =(l + r) >> ,tmp = sum[ch[tt][]] - sum[ch[ss][]];
if(k <= tmp) return query(ch[ss][],ch[tt][],l,Mid,k);
else return query(ch[ss][],ch[tt][],Mid + ,r,k - tmp);
}
};
PLTree P;
void _init()
{
Innum=cnt=;
sum1=sum2=sum3=;
}
void _scanf()
{
char chr[];
for(int i=;i<=n;i++){
scanf("%s",chr);
if(chr[]=='I'){
Qst[i].opt=;
scanf("%d",&Qst[i].x);
a[++Innum]=Qst[i].x;
b[Innum]=a[Innum];
}
else {
Qst[i].opt=chr[]-'';
if(chr[]=='') scanf("%d%d%d",&Qst[i].x,&Qst[i].y,&Qst[i].k);
else scanf("%d",&Qst[i].k);
}
}
}
void _disp()
{
sort(b+,b+Innum+);
for(int i=;i<=Innum;i++)
a[i]=lower_bound(b+,b+Innum+,a[i])-b;
}
void _work()
{
P.build(P.rt[],,Innum);
int nowcnt=,ans;
for(int i=;i<=n;i++){
if(Qst[i].opt==) {
nowcnt++;
P.insert(P.rt[nowcnt],P.rt[nowcnt-],,Innum,a[nowcnt]);
}
else if(Qst[i].opt==){
ans=P.query(P.rt[Qst[i].x-],P.rt[Qst[i].y],,Innum,Qst[i].k);
sum1+=b[ans];
}
else if(Qst[i].opt==){
int L=,R=nowcnt;
while(L<=R){
int Mid=(L+R)>>;
ans=P.query(P.rt[],P.rt[nowcnt],,Innum,Mid);
if(b[ans]==Qst[i].k) {
sum2+=Mid;
break;
}
else if(b[ans]<Qst[i].k) L=Mid+;
else R=Mid-;
}
}
else {
ans=P.query(P.rt[],P.rt[nowcnt],,Innum,Qst[i].k);
sum3+=b[ans];
}
}
printf("Case %d:\n",++Case);
printf("%lld\n%lld\n%lld\n",sum1,sum2,sum3);
}
int main()
{
while(~scanf("%d",&n)){
_init();
_scanf();//输入
_disp();//离散
_work();
}
return ;
}

操作2为树状数组的代码:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=;
int a[maxn],b[maxn],Innum,n;//a是位置,b是值。Innum是操作为输入的个数,即
int cnt,ql,qr,Case=;
long long sum1,sum2,sum3;
int c[maxn<<];
int lowbit(int x )
{
return x&-x;
}
void add( int x )
{
while(x < Innum){
c[x]++;
x += lowbit ( x );
}
}
int sum(int x )
{
int ret = ;
while (x){
ret += c[x];
x -= lowbit ( x );
}
return ret;
}
struct questions
{
int opt;//0,1,2,3
int x,y,k;
}Qst[maxn<<];
struct PLTree
{
int ch[maxn * ][],sum[maxn * ],rt[maxn];
void build(int& now,int l,int r)
{
now = ++ cnt;
sum[now] = ;
if(l == r) return ;
int Mid = (l + r)>>;
build(ch[now][],l,Mid);
build(ch[now][],Mid + ,r);
}
void insert(int& now,int last,int l,int r,int pos)
{
now = ++ cnt;
ch[now][]=ch[last][];
ch[now][]=ch[last][];
sum[now] = sum[last] + ;
if(l == r) return ;
int Mid = (l+r) >> ;
if(pos <= Mid) insert(ch[now][],ch[last][],l,Mid,pos);
else insert(ch[now][],ch[last][],Mid + ,r,pos);
}
int query(int ss,int tt,int l,int r,int k)
{
if(l == r) return l;
int Mid =(l + r) >> ,tmp = sum[ch[tt][]] - sum[ch[ss][]];
if(k <= tmp) return query(ch[ss][],ch[tt][],l,Mid,k);
else return query(ch[ss][],ch[tt][],Mid + ,r,k - tmp);
}
};
PLTree P;
void _init()
{
Innum=cnt=;
sum1=sum2=sum3=;
memset(c,,sizeof(c));
}
void _scanf()
{
char chr[];
for(int i=;i<=n;i++){
scanf("%s",chr);
if(chr[]=='I'){
Qst[i].opt=;
scanf("%d",&Qst[i].x);
a[++Innum]=Qst[i].x;
b[Innum]=a[Innum];
}
else {
Qst[i].opt=chr[]-'';
if(chr[]=='') scanf("%d%d%d",&Qst[i].x,&Qst[i].y,&Qst[i].k);
else scanf("%d",&Qst[i].k);
}
}
}
void _disp()
{
sort(b+,b+Innum+);
for(int i=;i<=Innum;i++)
a[i]=lower_bound(b+,b+Innum+,a[i])-b;
}
void _work()
{
P.build(P.rt[],,Innum);
int nowcnt=,ans;
for(int i=;i<=n;i++){
if(Qst[i].opt==) {
nowcnt++;
P.insert(P.rt[nowcnt],P.rt[nowcnt-],,Innum,a[nowcnt]);
add(a[nowcnt]);
}
else if(Qst[i].opt==){
ans=P.query(P.rt[Qst[i].x-],P.rt[Qst[i].y],,Innum,Qst[i].k);
sum1+=b[ans];
}
else if(Qst[i].opt==){
int tmp=sum(lower_bound(b+,b+Innum+,Qst[i].k)-b);
sum2+=tmp;
}
else {
ans=P.query(P.rt[],P.rt[nowcnt],,Innum,Qst[i].k);
sum3+=b[ans];
}
}
printf("Case %d:\n",++Case);
printf("%lld\n%lld\n%lld\n",sum1,sum2,sum3);
}
int main()
{
while(~scanf("%d",&n)){
_init();
_scanf();//输入
_disp();//离散
_work();
}
return ;
}

HDU3727 Jewel(主席树+树状数组(或二分))的更多相关文章

  1. 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分

    题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...

  2. [POJ2182]Lost Cows(树状数组,二分)

    题目链接:http://poj.org/problem?id=2182 题意:给定1~n个数和n个位置,已知ai表示第i个位置前有ai个数比当前位置的数小,求这个排列. 和刚才YY的题意蛮接近的,用树 ...

  3. BZOJ 2738 子矩阵第k大 | 二维树状数组 整体二分 分治

    BZOJ 2738 "矩阵乘法"(子矩阵第k大) 题意 给出一个矩阵,多次询问子矩阵中第k大的数是多少. 题解 我做这道题之前先照着这道题出了一道题,是这道题的一维版本,在这里:h ...

  4. 洛谷1527(bzoj2738)矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 不难想到(?)可以用二维树状数组.但维护什么?怎么查询是难点. 因为求第k小,可以考虑记权值树状数组,把比 ...

  5. POJ2828 Buy Tickets [树状数组,二分答案]

    题目传送门 Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 22611   Accepted: 110 ...

  6. 【洛谷3527】[POI2011] MET-Meteors(树状数组+整体二分)

    点此看题面 大致题意: 一颗星球被分为\(M\)份,分别属于\(N\)个国家,有\(K\)场陨石雨,第\(i\)个国家希望收集\(P_i\)颗陨石,问其至少要在第几次陨石雨后才能达到目标. 关于整体二 ...

  7. 洛谷P1527 矩阵乘法——二维树状数组+整体二分

    题目:https://www.luogu.org/problemnew/show/P1527 整体二分,先把所有询问都存下来: 然后二分一个值,小于它的加到二维树状数组的前缀和里,判断一遍所有询问,就 ...

  8. BZOJ3110[Zjoi2013]K大数查询(树状数组+整体二分)

    3110 [Zjoi2013]K大数查询 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a ...

  9. 2019牛客暑期多校训练营(第七场)E-Find the median(思维+树状数组+离散化+二分)

    >传送门< 题意:给n个操作,每次和 (1e9范围内)即往数组里面插所有 的所有数,求每次操作后的中位数思路:区间离散化然后二分答案,因为小于中位数的数字恰好有个,这显然具有单调性.那么问 ...

  10. Educational Codeforces Round 87 (Rated for Div. 2) D树状数组加二分删除的值

    Sample Input 5 4 1 2 3 4 5 -5 -1 -3 -1 Sample Output 3 思路,首先发现a[i]的值的范围是在1~n之间,每次插入我们可以直接把cnt[a[i]]+ ...

随机推荐

  1. [笔记]一道C语言面试题:IPv4字符串转为UInt整数

    题目:输入一个IPv4字符串,如“1.2.3.4”,输出对应的无符号整数,如本例输出为 0x01020304. 来源:某500强企业面试题目 思路:从尾部扫描到头部,一旦发现无法转换,立即返回,减少无 ...

  2. Archimate

    archimate语言提供了一种用于表示企业体系结构的图形化语言,包括策略,转换和迁移规划,以及架构的动机和基本原理.该标准的设计尽可能紧凑,但仍可用于大多数企业体系结构建模需求.下图显示了Archi ...

  3. Linux Shell编程 sort、wc命令

    sort命令:字符串排序 sort 命令可以依据不同的数据类型来进行排序.sort 将文件的每一行作为一个单位,相互比较.比较原则是从首字符向后,依次按 ASCII 码值进行比较,最后将它们按升序输出 ...

  4. 玩转python主题模型程序库gensim

    gensim是python下一个极易上手的主题模型程序库(topic model),网址在:http://radimrehurek.com/gensim/index.html 安装过程较为繁琐,参考h ...

  5. Qt事件机制---信号通过事件实现,事件可以过滤,事件更底层,事件是基础,信号是扩展。

    转:http://www.cnblogs.com/findumars/p/8001484.html Qt事件机制(是动作发生后,一种通知对象的消息,是被动与主动的总和.先处理自己队列中的消息,然后再处 ...

  6. 跨平台移动开发 Adobe Edge制作HTML5圣诞音乐贺卡DEMO

    1.新建项目 2.添加背景,图片,音频 var au_to_play=new Audio(); au_to_play.src="audio/lap.mp3"; //指定文件名,这里 ...

  7. unity json解析IPA后续

    以前说到的,有很大的限制,只能解析简单的类,如果复杂的就会有问题,从老外哪里看到一片博客,是将类中的list   等复杂对象序列化, using UnityEngine; using System.C ...

  8. js获取select标签选中的值[转]

    var obj = document.getElementByIdx_x(”testSelect”); //定位id var index = obj.selectedIndex; // 选中索引 va ...

  9. vim 乱码问题的方法参考

    linux 中设置当前用户的系统默认编码为 UTF-8 格式解决 vim 乱码问题的方法参考  任侠  2013-05-02 11:58  电脑基础  抢沙发  13,732 views  在使用 l ...

  10. ajax02-XMLHttpRequest 对象的使用

    XMLHttpRequest 是 AJAX 的基础,用于在后台与服务器交换数据.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. XMLHttpRequest 对象 所有现代浏览器均 ...