HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?
pid=5412
in CodeLand.
Boy i has
his coding skill Ai.
CRB wants to know who has the suitable coding skill.
So you should treat the following two types of queries.
Query 1: 1 l v
The coding skill of Boy l has
changed to v.
Query 2: 2 l r k
This is a report query which asks the k-th
smallest value of coding skill between Boy l and
Boy r(both
inclusive).
The first line contains a single integer N.
Next line contains N space
separated integers A1, A2,
…, AN,
where Ai denotes
initial coding skill of Boy i.
Next line contains a single integer Q representing
the number of queries.
Next Q lines
contain queries which can be any of the two types.
1 ≤ N, Q ≤ 105
1 ≤ Ai, v ≤ 109
1 ≤ l ≤ r ≤ N
1 ≤ k ≤ r – l +
1
5
1 2 3 4 5
3
2 2 4 2
1 3 6
2 2 4 2
3
4
题意:
给出一串数字。然后给出两种操作:
1:1 L V 操作一:把下标为L的点的值替换为 V
2:2 L R K 操作二:在[L, R]区间求第K大!
PS:
这题好像时间卡的比較紧!
貌似用树状数组套主席树会T
须要线段树套treap。
代码例如以下:
//#pragma warning (disable:4786)
//#pragma comment(linker,"/STACK:102400000,102400000") //手动扩栈
//#include <bits/stdc++.h>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <climits>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <deque>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps = 1e-9;
const double PI = acos(-1.00);
//#define PI 3.1415926535897932384626433832795
const double e = exp(1.0);
#define INF 0x3f3f3f3f
//#define INF 1e18
//typedef long long LL;
//typedef __int64 LL;
#define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif #define N 600010
#define M 100010
struct treap
{
int key,wht,count,sz,ch[2];
} tp[N*15];
int tree[N<<1];
int nodecount,root;
int IDX(int l,int r)
{
return l+r | l!=r;
}
void init()
{
tp[0].sz=0;
tp[0].wht=-INF;
nodecount=0;
root=0;
}
void update(int x)
{
tp[x].sz=tp[tp[x].ch[0]].sz+tp[x].count+tp[tp[x].ch[1]].sz;
}
void rotate(int &x,int t)
{
int y=tp[x].ch[t];
tp[x].ch[t]=tp[y].ch[!t];
tp[y].ch[!t]=x;
update(x);
update(y);
x=y;
}
void insert(int &x,int t)
{
if(! x)
{
x=++nodecount;
tp[x].key=t;
tp[x].wht=rand();
tp[x].count=1;
tp[x].ch[0]=tp[x].ch[1]=0;
}
else if(tp[x].key==t) tp[x].count++;
else
{
int k=tp[x].key<t;
insert(tp[x].ch[k],t);
if(tp[x].wht<tp[tp[x].ch[k]].wht) rotate(x,k);
}
update(x);
}
void erase(int &x,int t)
{
if(tp[x].key==t)
{
if(tp[x].count==1)
{
if(! tp[x].ch[0] && ! tp[x].ch[1])
{
x=0;
return;
}
rotate(x,tp[tp[x].ch[0]].wht<tp[tp[x].ch[1]].wht);
erase(x,t);
}
else tp[x].count--;
}
else erase(tp[x].ch[tp[x].key<t],t);
update(x);
}
int select(int x,int t)
{
if(! x) return 0;
if(tp[x].key>t) return select(tp[x].ch[0],t);
return tp[x].count+tp[tp[x].ch[0]].sz+select(tp[x].ch[1],t);
}
int a[N],b[N],ord[M][5],lb;
int n,m,tt;
int search(int x)
{
int l=1,r=b[0],mid;
while (l<=r)
{
mid=(l+r)>>1;
if(b[mid]==x) return mid;
if(b[mid]<x) l=mid+1;
else r=mid-1;
}
}
void treeinsert(int l,int r,int i,int x)
{
insert(tree[IDX(l,r)],x);
if(l==r) return;
int m=(l+r)>>1;
if(i<=m) treeinsert(l,m,i,x);
else treeinsert(m+1,r,i,x);
}
void treedel(int l,int r,int i,int x)
{
erase(tree[IDX(l,r)],x);
if(l==r) return;
int m=(l+r)>>1;
if(i<=m) treedel(l,m,i,x);
else treedel(m+1,r,i,x);
}
int query(int l,int r,int x,int y,int k)
{
if(l==r) return l;
int m=(l+r)>>1;
int ans=select(tree[IDX(l,m)],y)-select(tree[IDX(l,m)],x);
if(ans>=k) return query(l,m,x,y,k);
return query(m+1,r,x,y,k-ans);
}
int main ()
{
while (~scanf("%d",&n))
{
b[0]=1;
lb=0;
memset(tree,0,sizeof(tree));
init();
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
b[++lb]=a[i];
}
scanf("%d",&m);
for(int i=1; i<=m; i++)
{
int op;
int x,y,c;
scanf("%d",&op);
if(op == 2)
{
scanf("%d %d %d",&x,&y,&c);
ord[i][1]=1;
ord[i][2]=x;
ord[i][3]=y;
ord[i][4]=c;
}
else
{
scanf("%d %d",&x,&y);
ord[i][1]=2;
ord[i][2]=x;
ord[i][3]=y;
b[++lb]=y;
}
}
sort(b+1,b+1+lb);
for(int i=1; i<=lb; i++)
if(b[i]!=b[b[0]]) b[++b[0]]=b[i];
for(int i=1; i<=n; i++)
{
a[i]=search(a[i]);
treeinsert(1,b[0],a[i],i);
}
for(int i=1; i<=m; i++)
{
if(ord[i][1]==1)
printf("%d\n",b[query(1,b[0],ord[i][2]-1,ord[i][3],ord[i][4])]);
else
{
treedel(1,b[0],a[ord[i][2]],ord[i][2]);
a[ord[i][2]]=search(ord[i][3]);
treeinsert(1,b[0],a[ord[i][2]],ord[i][2]);
}
}
}
return 0;
}
HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)的更多相关文章
- 静态区间第k大(归并树)
POJ 2104为例 思想: 利用归并排序的思想: 建树过程和归并排序类似,每个数列都是子树序列的合并与排序. 查询过程,如果所查询区间完全包含在当前区间中,则直接返回当前区间内小于所求数的元素个数, ...
- hdu 5412 CRB and Queries
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5412 CRB and Queries Description There are $N$ boys i ...
- hdu 5412 CRB and Queries(整体二分)
题意 动态区间第k大 (n<=100000,m<=100000) 题解 整体二分的应用. 与静态相比差别不是很大.(和CDQ还有点像)所以直接上代码. #include<iostre ...
- POJ 2104 && POJ 2761 (静态区间第k大,主席树)
查询区间第K大,而且没有修改. 使用划分树是可以做的. 作为主席树的入门题,感觉太神奇了,Orz /* *********************************************** ...
- 静态区间第k大(主席树)
POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...
- HDU 5412——CRB and Queries——————【线段树套Treap(并没有AC)】
CRB and Queries Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- 2015 Multi-University Training Contest 10 hdu 5412 CRB and Queries
CRB and Queries Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- HDU - 5412 CRB and Queries (整体二分)
题目链接 动态区间第k小,但是这道题的话用主席树+树状数组套线段树的空间复杂度是O(nlog2n)会爆掉. 另一种替代的方法是用树状数组套平衡树,空间复杂度降到了O(nlogn),但我感觉平衡树是个挺 ...
- 静态区间第k大(划分树)
POJ 2104为例[经典划分树问题] 思想: 利用快速排序思想, 建树时将区间内的值与区间中值相比,小于则放入左子树,大于则放入右子树,如果相等则放入左子树直到放满区间一半. 查询时,在建树过程中利 ...
随机推荐
- Eclipse 添加本地 SVN插件以及运行项目的流程
去网上下载SVN插件包.里面包含文件如图: 把features和plugins文件夹里面的东西全部复制粘贴到eclipse安装目录下的features和plugins文件夹中就行.然后重启eclips ...
- Microsoft SQL Server 2005技术内幕:T-SQL查询笔记
logical operation:基于微软查询处理概念模型的逻辑操作.例如,联接运算符的physical operation属性表示联接算法(nested loops,merge ,hash)物理运 ...
- 安卓手机USB无法共享、上网或卡顿的解决方法
安卓手机通过USB为电脑(Windows10)提供网络接入点时,系统程序会异常卡顿. 1)设备管理器2)点击“网络适配器”,在弹出的下拉列表中选择”Remote NDIS based Internet ...
- DE2之7-segment displays
以前课题用的是友晶的DE2-70,现在重拾FPGA,选了一款性价比高的DE2.恰逢闲来无事,于是尝试将各个Verilog模块翻译成VHDL,半算回顾以前的知识,半算练习VHDL. Verilog 01 ...
- 时序分析:ARMA方法(平稳序列)
憔悴到了转述中文综述的时候了........ 在统计学角度来看,时间序列分析是统计学中的一个重要分支, 是基于随机过程理论和数理统计学的一种重要方法和应用研究领域. 时间序列按其统计特性可分为平稳性 ...
- 【sqli-labs】 less17 POST - Update Query- Error Based - String (基于错误的更新查询POST注入)
这是一个重置密码界面,查看源码可以看到username作了防注入处理 逻辑是先通过用户名查出数据,在进行密码的update操作 所以要先知道用户名,实际情况中可以注册用户然后实行攻击,这里先用admi ...
- 备份xx
https://www.tuicool.com/articles/V3EBzev https://www.tuicool.com/topics/11080087?st=0&lang=1& ...
- windows10上安装mysql详细图文教程
在windows10上安装mysql详细图文教程 这篇文章主要介绍了在windows10上安装mysql详细图文教程,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看看吧 环境:windw ...
- 被遗忘的 Logrotate
转自: http://huoding.com/2013/04/21/246 被遗忘的 Logrotate 发表于 2013-04-21 我发现很多人的服务器上都运行着一些诸如每天切分 Nginx 日志 ...
- echarts在地图上绘制散点图(任意点)
项目需求:在省份地图上绘制散点图,散点位置不一定是哪个城市或哪个区县,即任意点 通过查询官网文档,找到一个与需求类似的Demo:https://www.echartsjs.com/gallery/ed ...