【函数式权值分块】【分块】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.... -------------------------------------------------------------------- ...
随机推荐
- power designer 绘制E-R 图
总体概括:本篇主要先介绍E-R图的一些基本概念,然后介绍怎么绘制E-R图,特别是用power designer 的反向工程怎么把表中对字段的注释也展示出来. 1.E-R图的基本概念: E-R图就是en ...
- im4java学习---阅读documentation文档
Utilities----im提供的一些工具类 ①.读取图片文件信息---Info类 我们之前的做法: op.format("width:%w,height:%h,path:%d%f,siz ...
- notepad++中快速插入当前时间方法
转载自:http://blog.csdn.net/donghustone/article/details/7436483 在notepad++中快速插入当前时间方法: 插件是notepad++的一大优 ...
- C#网络编程基本字段---IPAddress、IPEndPoint
命名空间: using System.Net; PAddress类提供了对IP地址的转换.处理等功能.其Parse方法可将IP地址字符串转换为IPAddress实例. 如:IPAddress ip = ...
- 【洛谷 P3846】 [TJOI2007]可爱的质数 (BSGS)
题目链接 \(BSGS\)模板题..不会点这里 #include <cstdio> #include <cmath> #include <map> using na ...
- 【洛谷 P1445】 [Violet]樱花(唯一分解定理)
做了题还是忍不住要写一发题解,感觉楼下的不易懂啊. 本题解使用latex纯手写精心打造. 题意:求\(\frac{1}{x}+\frac{1}{y}=\frac{1}{n!}\)的正整数解总数. 首先 ...
- [bzoj3524==bzoj2223][Poi2014]Couriers/[Coci 2009]PATULJCI——主席树+权值线段树
题目大意 给定一个大小为n,每个数的大小均在[1,c]之间的数列,你需要回答m个询问,其中第i个询问形如\((l_i, r_i)\),你需要回答是否存在一个数使得它在区间\([l_i,r_i]\)中出 ...
- 【git】git提交忽略不必要的文件或文件夹
对于经常使用Git的朋友来说,.gitignore配置一定不会陌生.废话不说多了,接下来就来说说这个.gitignore的使用. 首先要强调一点,这个文件的完整文件名就是".gitignor ...
- UVALIVE 5096 Volume
This time your job is to calculate the volume of a special object. The object consists of two orthog ...
- 细说robots.txt
robots.txt Robots协议(也称为爬虫协议.机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可 ...