【函数式权值分块】【分块】bzoj3196 Tyvj 1730 二逼平衡树
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 50001
#define SQRT 227
int n,m,xs[N],ys[N],ks[N],op[N],en,ma[100001],en2,a[100001];
int num[N],l[SQRT],r[SQRT],sumv[SQRT],sum=1;//分块
int num2[100001],l2[320],r2[320],tot=1;//函数式权值分块
struct Point{int v,p;}t[100001];
bool operator < (const Point &a,const Point &b){return a.v<b.v;}
struct Val_Block
{
int b[100001],sumv[320];
void Insert(const int &x){++b[x]; ++sumv[num2[x]];}
void Delete(const int &x){--b[x]; --sumv[num2[x]];}
}T[SQRT],S;
void makeblock()
{
int sz=sqrt(n);
if(!sz) sz=1;
for(;sum*sz<n;++sum)
{
l[sum]=r[sum-1]+1;
r[sum]=sum*sz;
for(int i=l[sum];i<=r[sum];++i)
num[i]=sum;
}
l[sum]=r[sum-1]+1;
r[sum]=n;
for(int i=l[sum];i<=r[sum];++i)
num[i]=sum;
}
void val_mb()
{
int sz=sqrt(en2);
if(!sz) sz=1;
for(;tot*sz<en2;++tot)
{
l2[tot]=r2[sum-1]+1;
r2[tot]=tot*sz;
for(int i=l2[tot];i<=r2[tot];++i)
num2[i]=tot;
}
l2[tot]=r2[sum-1]+1;
r2[tot]=en2;
for(int i=l2[tot];i<=r2[tot];++i)
num2[i]=tot;
}
void Init_Ts()
{
for(int i=1;i<=sum;++i)
{
T[i]=T[i-1];
for(int j=l[i];j<=r[i];++j)
T[i].Insert(a[j]);
}
}
int Kth(const int &L,const int &R,const int &x)
{
int cnt=0,res;
if(num[L]+1>=num[R])
{
for(int i=L;i<=R;++i)
S.Insert(a[i]);
for(int i=1;;++i)
{
cnt+=S.sumv[i];
if(cnt>=x)
{
cnt-=S.sumv[i];
for(int j=l2[i];;++j)
{
cnt+=S.b[j];
if(cnt>=x)
{
res=j;
goto OUT2;
}
}
}
}
OUT2:for(int i=L;i<=R;++i)
S.Delete(a[i]);
return res;
}
for(int i=L;i<=r[num[L]];++i)
S.Insert(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Insert(a[i]);
int LB=num[L],RB=num[R]-1;
for(int i=1;;++i)
{
cnt+=(T[RB].sumv[i]-T[LB].sumv[i]+S.sumv[i]);
if(cnt>=x)
{
cnt-=(T[RB].sumv[i]-T[LB].sumv[i]+S.sumv[i]);
for(int j=l2[i];;++j)
{
cnt+=(T[RB].b[j]-T[LB].b[j]+S.b[j]);
if(cnt>=x)
{
res=j;
goto OUT;
}
}
}
}
OUT:for(int i=L;i<=r[num[L]];++i)
S.Delete(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Delete(a[i]);
return res;
}
int Rank(const int &L,const int &R,const int &x)
{
int cnt=0;
if(num[L]+1>=num[R])
{
for(int i=L;i<=R;++i)
S.Insert(a[i]);
for(int i=1;i<num2[x];i++)
cnt+=S.sumv[i];
for(int i=l2[num2[x]];i<x;i++)
cnt+=S.b[i];
for(int i=L;i<=R;++i)
S.Delete(a[i]);
return cnt+1;
}
for(int i=L;i<=r[num[L]];++i)
S.Insert(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Insert(a[i]);
int LB=num[L],RB=num[R]-1;
for(int i=1;i<num2[x];i++)
cnt+=(T[RB].sumv[i]-T[LB].sumv[i]+S.sumv[i]);
for(int i=l2[num2[x]];i<x;i++)
cnt+=(T[RB].b[i]-T[LB].b[i]+S.b[i]);
for(int i=L;i<=r[num[L]];++i)
S.Delete(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Delete(a[i]);
return cnt+1;
}
int f,c;
inline void R(int &x){
c=0;f=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
for(x=0;c>='0'&&c<='9';c=getchar())(x*=10)+=(c-'0');
x*=f;
}
void P(int x){
if(x<10)putchar(x+'0');
else{P(x/10);putchar(x%10+'0');}
}
int Next(const int &L,const int &R,const int &x)
{
int res;
if(num[L]+1>=num[R])
{
for(int i=L;i<=R;++i)
S.Insert(a[i]);
for(int i=x+1;i<=r2[num2[x]];i++)
if(S.b[i])
{
res=i;
goto OUT2;
}
for(int i=num2[x]+1;;i++)
if(S.sumv[i])
for(int j=l2[i];;j++)
if(S.b[j])
{
res=j;
goto OUT2;
}
OUT2:for(int i=L;i<=R;++i)
S.Delete(a[i]);
return res;
}
for(int i=L;i<=r[num[L]];++i)
S.Insert(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Insert(a[i]);
int LB=num[L],RB=num[R]-1;
for(int i=x+1;i<=r2[num2[x]];i++)
if((T[RB].b[i]-T[LB].b[i]+S.b[i]))
{
res=i;
goto OUT;
}
for(int i=num2[x]+1;;i++)
if((T[RB].sumv[i]-T[LB].sumv[i]+S.sumv[i]))
for(int j=l2[i];;j++)
if((T[RB].b[j]-T[LB].b[j]+S.b[j]))
{
res=j;
goto OUT;
}
OUT:for(int i=L;i<=r[num[L]];++i)
S.Delete(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Delete(a[i]);
return res;
}
int Pre(const int &L,const int &R,const int &x)
{
int res;
if(num[L]+1>=num[R])
{
for(int i=L;i<=R;++i)
S.Insert(a[i]);
for(int i=x-1;i>=l2[num2[x]];i--)
if(S.b[i])
{
res=i;
goto OUT2;
}
for(int i=num2[x]-1;;i--)
if(S.sumv[i])
for(int j=r2[i];;j--)
if(S.b[j])
{
res=j;
goto OUT2;
}
OUT2:for(int i=L;i<=R;++i)
S.Delete(a[i]);
return res;
}
for(int i=L;i<=r[num[L]];++i)
S.Insert(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Insert(a[i]);
int LB=num[L],RB=num[R]-1;
for(int i=x-1;i>=l2[num2[x]];i--)
if((T[RB].b[i]-T[LB].b[i]+S.b[i]))
{
res=i;
goto OUT;
}
for(int i=num2[x]-1;;i--)
if((T[RB].sumv[i]-T[LB].sumv[i]+S.sumv[i]))
for(int j=r2[i];;j--)
if((T[RB].b[j]-T[LB].b[j]+S.b[j]))
{
res=j;
goto OUT;
}
OUT:for(int i=L;i<=r[num[L]];++i)
S.Delete(a[i]);
for(int i=l[num[R]];i<=R;++i)
S.Delete(a[i]);
return res;
}
int main()
{
R(n);
R(m);
makeblock();
en=n;
for(int i=1;i<=n;++i)
R(t[i].v),
t[i].p=i;
for(int i=1;i<=m;++i)
{
R(op[i]);
if(op[i]==3)
R(xs[i]),R(ks[i]);
else
R(xs[i]),R(ys[i]),R(ks[i]);
if(op[i]!=2)
t[++en].v=ks[i],
t[en].p=en;
}
sort(t+1,t+en+1);
ma[a[t[1].p]=++en2]=t[1].v;
for(int i=2;i<=en;++i)
{
if(t[i].v!=t[i-1].v)
++en2;
ma[a[t[i].p]=en2]=t[i].v;
}
val_mb();
Init_Ts();
en=n;
for(int i=1;i<=m;++i)
{
if(op[i]!=2)
++en;
if(op[i]==3)
{
for(int j=num[xs[i]];j<=sum;++j)
T[j].Delete(a[xs[i]]),T[j].Insert(a[en]);
a[xs[i]]=a[en];
}
else if(op[i]==2)
P(ma[Kth(xs[i],ys[i],ks[i])]),puts("");
else if(op[i]==1)
P(Rank(xs[i],ys[i],a[en])),puts("");
else if(op[i]==4)
P(ma[Pre(xs[i],ys[i],a[en])]),puts("");
else
P(ma[Next(xs[i],ys[i],a[en])]),puts("");
}
return 0;
}
【函数式权值分块】【分块】bzoj3196 Tyvj 1730 二逼平衡树的更多相关文章
- 【带修莫队】【权值分块】bzoj3196 Tyvj 1730 二逼平衡树
这题用了三种算法写: 分块+二分:O(n*sqrt(n*log(n)) 函数式权值分块:O(n*sqrt(n)) 带修莫队+权值分块:O(n5/3) 结果……复杂度越高的实际上跑得越快……最后这个竟然 ...
- 【分块】bzoj3196 Tyvj 1730 二逼平衡树
分块 或 树套树. 在每个块中维护一个有序表,查询时各种二分,全都是分块的经典操作,就不详细说了. 块的大小定为sqrt(n*log2(n))比较快. #include<cstdio> # ...
- 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][二逼平衡树] (线段树套treap)
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...
- [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树
题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...
- BZOJ3196: Tyvj 1730 二逼平衡树
传送门 主席树的常数蜜汁优越,在BZOJ上跑了rnk1. 做法很简单,主席树套BIT. 1-3做法很简单,第四个和第五个做法转换成前两个就行了. //BZOJ 3196 //by Cydiater / ...
- 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.... -------------------------------------------------------------------- ...
随机推荐
- oralce的客户端sqlplus
安装完oracle后,默认的客户端是sqlplus,还有一个公司常用的是PLSQLdeveloper 客户端软件,另外Navicat primie这个可以连接mysql.sqlserver.oracl ...
- bzoj 5094 [Lydsy1711月赛]硬盘检测 概率dp
[Lydsy1711月赛]硬盘检测 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 273 Solved: 75[Submit][Status][Dis ...
- linux内存条排查
已发现2个内存错误,应用名称(kernel:),日志内容(hangzhou-jishuan-DDS0248 kernel: sbridge: HANDLING MCE MEMORY ERROR han ...
- 【转载】惊天大悲剧-Hadoop的rmr和trash
转自:http://java-doom.iteye.com/blog/1898000 这两天在操作Hadoop集群时,由于一个误操作,制作了一个天大的悲剧 不小心把Hadoop集群上的所有文件全部删除 ...
- Ubuntu gnome 16.04下的一些个人配置
虽说并没有改什么,但还是花了我很长时间去搞明白…… 最开始要看下这里,调下比如系统时间等东西 UPD:安装时千万不要对主目录进行加密 1.登录前调整一下触控板和打开小键盘 先打开/etc/gdm3/I ...
- 解决tomcat不支持中文路径的问题
问题描述: 开发文件下载功能时,因为需求比较简单,要求下载一个说明文件.于是,直接给出了文件所在服务器的地址,通过链接直接下载此文件(因需求简单,未考虑安全方面的问题-_-||). 在这个过程中,文件 ...
- bzoj4128 Matrix
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128 [题解] 矩阵版本的BSGS. 至于如何不需要求逆,详见:http://www.cnb ...
- 【洛谷 P1363】幻想迷宫(搜索)
这题其实可以很简单. 题目叫做"幻想迷宫",那么我们就幻想一个迷宫. 借用一下@FancyDreams的图片 只有左上角第一个\(5*4\)的迷宫是真的, 其他都是我们幻想出来的. ...
- keras_实现cnn_手写数字识别
# conding:utf-8 import os os.environ[' import numpy as np from keras.models import Sequential from k ...
- python基础之函数(自定义函数)
函数: 函数的定义: 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数. ...