【函数式权值分块】【分块】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.... -------------------------------------------------------------------- ...
随机推荐
- spring中Constructor、@Autowired、@PostConstruct的顺序【转】
其实从依赖注入的字面意思就可以知道,要将对象p注入到对象a,那么首先就必须得生成对象p与对象a,才能执行注入.所以,如果一个类A中有个成员变量p被@Autowired注解,那么@Autowired注入 ...
- Ubuntu下安装LNMP之Mysql的安装及卸载
Mysql的安装过程也可参考:http://blog.csdn.net/qq_20565303/article/details/69813868 Mysql安装包下载地址:https://dev.my ...
- SQL 学习小笔记
1.FOUND_ROWS() 题目: ,; 在上边sql中使用什么选项可以使 SELECT FOUND_ROWS()忽略LIMIT子句,返回总数? *答案* : SQL_CALC_FOUND_ROWS ...
- JQuery如何监听DIV内容变化
这几天在做一个微博的接入,需要判断微博是否被关注,要检查微博标签的DIV是否有“已关注”的字符,但这个DIV的内容是微博JSSDK动态生 成.$("#id").html()是获取不 ...
- 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...
- 使用腾讯云 GPU 学习深度学习系列之二:Tensorflow 简明原理【转】
转自:https://www.qcloud.com/community/article/598765?fromSource=gwzcw.117333.117333.117333 这是<使用腾讯云 ...
- Oracle基础 11 约束 constraints
--主.外键约束 create table t( id int primary key); create table t1( id int references t(id)); 或者create ...
- unity学习笔记1--Space Shooter
其实我一直觉得我是个模棱两可的人,就计算机这块来说,自己还是想制作游戏什么的,但是又得考虑到现实就业的问题,所以现在自己主要在学安卓和javaweb.现在大概是心血来潮吧,突然想追逐下自己的理想,虽然 ...
- java callable future futuretask
Runnbale封装一个异步运行的任务,可以把它想象成一个没有任何参数和返回值的异步方法.Callable和Runnable相似,但是它有返回值.Callable接口是参数化的类型,只有一个方法cal ...
- 虚拟机vmware下安装Ghost XP——正确的解决方案
http://hi.baidu.com/xjl456852/item/fd466e9935b2da8859146111 在虚拟机中启动系统,出现"Operating System not f ...