BZOJ3196: Tyvj 1730 二逼平衡树
主席树的常数蜜汁优越,在BZOJ上跑了rnk1。
做法很简单,主席树套BIT。
1-3做法很简单,第四个和第五个做法转换成前两个就行了。
//BZOJ 3196
//by Cydiater
//2016.12.10
#include <iostream>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <cstring>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <set>
#include <vector>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
#define FILE "psh"
const int MAXN=5e4+5;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int N,M,root[MAXN<<1],arr[MAXN],fsort[MAXN<<1],rnum,cnt=0,top[2],preL[MAXN],preR[MAXN],tmpL[MAXN],tmpR[MAXN],TMP;
struct Chair_man_Tree{
int son[2],sum;
}t[MAXN<<6];
struct Query{
int opt,L,R,pos,K;
}query[MAXN];
namespace solution{
inline int lowbit(int i){return ((i)&(-i));}
int NewNode(int sum,int son0,int son1){
t[++cnt].sum=sum;t[cnt].son[0]=son0;t[cnt].son[1]=son1;
return cnt;
}
void insert(int leftt,int rightt,int &Root,int last,int pos){
Root=NewNode(t[last].sum+1,t[last].son[0],t[last].son[1]);
int mid=(leftt+rightt)>>1;
if(leftt==rightt) return;
if(pos<=mid) insert(leftt,mid,t[Root].son[0],t[last].son[0],pos);
else insert(mid+1,rightt,t[Root].son[1],t[last].son[1],pos);
}
void PushTree(int L,int R){
top[0]=top[1]=0;
preL[++top[0]]=root[(L-1==0?0:(N+L-1))];
preR[++top[1]]=root[R+N];
for(int j=L-1;j>=1;j-=lowbit(j)) preL[++top[0]]=root[j];
for(int j=R;j>=1;j-=lowbit(j)) preR[++top[1]]=root[j];
}
void ChooseLeft(){
up(i,1,top[0])preL[i]=t[preL[i]].son[0];
up(i,1,top[1])preR[i]=t[preR[i]].son[0];
}
void ChooseRight(){
up(i,1,top[0])preL[i]=t[preL[i]].son[1];
up(i,1,top[1])preR[i]=t[preR[i]].son[1];
}
int Col(){
int sum=0;
up(i,1,top[0])sum-=t[t[preL[i]].son[0]].sum;
up(i,1,top[1])sum+=t[t[preR[i]].son[0]].sum;
return sum;
}
void Prepare(){
rnum=N=read();M=read();
up(i,1,N)arr[i]=fsort[i]=read();
up(i,1,M){
query[i].opt=read();
if(query[i].opt==3){
query[i].pos=read();query[i].K=read();
fsort[++rnum]=query[i].K;continue;
}
query[i].L=read();query[i].R=read();query[i].K=read();
if(query[i].opt==4||query[i].opt==5)
fsort[++rnum]=query[i].K;
}
sort(fsort+1,fsort+rnum+1);
rnum=unique(fsort+1,fsort+rnum+1)-(fsort+1);
up(i,1,N){
arr[i]=lower_bound(fsort+1,fsort+rnum+1,arr[i])-fsort;
insert(1,rnum,root[i+N],root[i+N-1],arr[i]);
}
}
int Rank(int leftt,int rightt,int pos){
if(leftt==rightt){
TMP=0;
up(i,1,top[0])TMP-=t[preL[i]].sum;
up(i,1,top[1])TMP+=t[preR[i]].sum;
return 1;
}
int sum=0,mid=(leftt+rightt)>>1;
sum=Col();
if(pos<=mid){
ChooseLeft();
return Rank(leftt,mid,pos);
}else{
ChooseRight();
return sum+Rank(mid+1,rightt,pos);
}
}
int Get(int leftt,int rightt,int rnk){
int sum,mid=(leftt+rightt)>>1;
if(leftt==rightt) return fsort[leftt];
sum=Col();
if(rnk<=sum){
ChooseLeft();
return Get(leftt,mid,rnk);
}else{
ChooseRight();
return Get(mid+1,rightt,rnk-sum);
}
}
void Insert(int leftt,int rightt,int &Root,int pos,int tag){
if(!Root)Root=NewNode(0,0,0);
t[Root].sum+=tag;
if(leftt==rightt) return;
int mid=(leftt+rightt)>>1;
if(pos<=mid) Insert(leftt,mid,t[Root].son[0],pos,tag);
else Insert(mid+1,rightt,t[Root].son[1],pos,tag);
}
void Slove(){
up(i,1,M){
int opt=query[i].opt;
if(opt==1){
int L=query[i].L,R=query[i].R,K=lower_bound(fsort+1,fsort+rnum+1,query[i].K)-fsort;
PushTree(L,R);
printf("%d\n",Rank(1,rnum,K));
}
if(opt==2){
int L=query[i].L,R=query[i].R,K=query[i].K;
PushTree(L,R);
printf("%d\n",Get(1,rnum,K));
}
if(opt==3){
int Pos=query[i].pos,K=query[i].K;
for(int j=Pos;j<=N;j+=lowbit(j))
Insert(1,rnum,root[j],arr[Pos],-1);
arr[Pos]=lower_bound(fsort+1,fsort+rnum+1,K)-fsort;
for(int j=Pos;j<=N;j+=lowbit(j))
Insert(1,rnum,root[j],arr[Pos],1);
}
if(opt==4){
int L=query[i].L,R=query[i].R,K=lower_bound(fsort+1,fsort+rnum+1,query[i].K)-fsort;
PushTree(L,R);
int rank=Rank(1,rnum,K);
PushTree(L,R);
printf("%d\n",Get(1,rnum,rank-1));
}
if(opt==5){
int L=query[i].L,R=query[i].R,K=lower_bound(fsort+1,fsort+rnum+1,query[i].K)-fsort;
PushTree(L,R);
int rank=Rank(1,rnum,K);
PushTree(L,R);
printf("%d\n",Get(1,rnum,rank+TMP));
}
}
}
}
int main(){
using namespace solution;
Prepare();
Slove();
return 0;
}
BZOJ3196: Tyvj 1730 二逼平衡树的更多相关文章
- bzoj3196: Tyvj 1730 二逼平衡树 树套树
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196 题目: 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec ...
- 【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树
线段树套pb_ds里的平衡树,在洛谷OJ上测试,后三个测试点TLE #include<cstdio> #include<algorithm> #include<ext/p ...
- [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树
题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...
- [bzoj3196][Tyvj 1730][二逼平衡树] (线段树套treap)
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
- 【分块】bzoj3196 Tyvj 1730 二逼平衡树
分块 或 树套树. 在每个块中维护一个有序表,查询时各种二分,全都是分块的经典操作,就不详细说了. 块的大小定为sqrt(n*log2(n))比较快. #include<cstdio> # ...
- 【带修莫队】【权值分块】bzoj3196 Tyvj 1730 二逼平衡树
这题用了三种算法写: 分块+二分:O(n*sqrt(n*log(n)) 函数式权值分块:O(n*sqrt(n)) 带修莫队+权值分块:O(n5/3) 结果……复杂度越高的实际上跑得越快……最后这个竟然 ...
- 【函数式权值分块】【分块】bzoj3196 Tyvj 1730 二逼平衡树
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...
- bzoj 3196 Tyvj 1730 二逼平衡树(线段树套名次树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1807 Solved: 772[Submit][Stat ...
- BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )
这道题做法应该很多吧.... 我用了线段树套treap.... -------------------------------------------------------------------- ...
随机推荐
- CentOS7安装docker
1. 查看系统版本 $ cat /etc/redhat-release 2. 安装docker $ yum install docker 3.检查安装是否成功$ docker version 若 ...
- Java Web之网上购物系统(提交订单、查看我的订单)
作业终于做完了,好开心......虽然这一周经历不是那么顺利,但是觉得还是收获了不少,有过想哭的冲动,代码不会写,事情办不好,各种发愁.空间里发小发了带父母出去游玩的照片,瞬间能量值不知道是被击退的多 ...
- IO流的登录与注册
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileR ...
- MySQL可视化软件Work Bench导出导入数据库
首先打开你的work bench,输入你的密码进入主页面 A:导入数据库 在Schemas空白处右键选择Create~:建立一个数据库,然后就可以导入你的sql文件了 File-->Open S ...
- currentStyle与getComputedStyle应用
getComputedStyle获取的是计算机(浏览器)计算后的样式,但是不兼容IE6.7.8(主要用于非IE浏览器) currentStyle方法兼容IE6.7.8,但是不兼容标准浏览器(主要用于I ...
- Jmeter+TCP\Scoket(8583)报文压力测试
Jmeter一般被用来测试HTTP协议,我第一次拿来测试socket协议,pos机传输报文为8583,协议属于socket,也是TCP协议的一种,网上有LR怎么测试8583报文,我就研究了一下怎么用J ...
- Struts2入门案例
struts2最简便的案例 Struts 2是一个MVC框架,以WebWork框架的设计思想为核心,吸收了Struts 1的部分优点.Struts 2拥有更加广阔的前景,自身功能强大,还对其他框架 ...
- ios开发中的小技巧
在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...
- redis字符串
字符串类型是redis的基本类型 字符串数据类型的相关命令用于管理 redis 字符串值,基本语法如下:COMMAND KEY_NAME SET 和GET用于设置和读取key的值 1.SET key ...
- [LeetCode] Employees Earning More Than Their Managers 员工挣得比经理多
The Employee table holds all employees including their managers. Every employee has an Id, and there ...