【函数式权值分块】【分块】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.... -------------------------------------------------------------------- ...
随机推荐
- 移动端浏览器touch事件的研究总结
$("body").on("touchstart", function(e) { e.preventDefault(); startX = e. ...
- WebKit学习资源
1.http://blog.csdn.net/dlmu2001/article/category/741748 红心地瓜 2.http://blog.csdn.net/cnnzp/article ...
- c++对拍实现
直接上代码吧. #include<bits/stdc++.h> using namespace std; int main(){ while(1){ system("./cute ...
- windows下mysql 5.7的配置全过程
这是一套在好多次的安装下总结出来的经验,包括很多种遇到的问题,查过很多资料,特此总结一下. 一.从官网下载MySQL的zip(免安装的) 解压mysql-5.7.11-winx64.zip到自己指定的 ...
- 1552: [Cerc2007]robotic sort
这道题用splay写 先离散化数据保证按题目所述顺序来写 按原序作为键值建树 维护区间最小值去跑 每次将i的位置 和 n的位置x和y找出来后 将x旋转到root y旋转到x的有儿子 这时y的左子树就是 ...
- C++ 异常~一 转
C++ 异常机制分析 阅读目录 C++异常机制概述 throw 关键字 异常对象 catch 关键字 栈展开.RAII 异常机制与构造函数 异常机制与析构函数 noexcept修饰符与noexce ...
- linux基础编程 套接字socket 完整的服务器端多线程socket程序【转】
转自:http://blog.csdn.net/ghostyu/article/details/7737203 此段程序来自我的一个项目中,稍微做了些修改,运行稳定,客户端程序比较简单所以未编写,可以 ...
- UVALIVE 5096 Volume
This time your job is to calculate the volume of a special object. The object consists of two orthog ...
- appium===安卓SDK下载很慢的解决办法
方法一:http://www.apkbus.com/forum.php?mod=viewthread&tid=240851 方法二:http://www.androiddevtools.cn/
- Cause: org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: java.sql.SQLException: 不支持的特性
mybatis插入数据时报错: Cause: org.apache.ibatis.executor.ExecutorException: Error getting generated key or ...