这题用了三种算法写:

分块+二分:O(n*sqrt(n*log(n))

函数式权值分块:O(n*sqrt(n))

带修莫队+权值分块:O(n5/3)

结果……复杂度越高的实际上跑得越快……最后这个竟然进第一页了……

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
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');}
}
#define N 50001
#define BN 320
int n,m,c[N],a[N<<1],enc,enq,num2[N],ma[N<<1],anss[N],en,en2;
struct Point{int v,p;}t[N<<1];
bool operator < (const Point &a,const Point &b){return a.v<b.v;}
struct ASK{int op,l,r,k,p,t;}Q[N];
bool operator < (const ASK &a,const ASK &b)
{
if(num2[a.l]==num2[b.l])
{
if(num2[a.r]==num2[b.r])
return a.t<b.t;
return num2[a.r]<num2[b.r];
}
return num2[a.l]<num2[b.l];
}
struct UPT{int x,y,z;}CH[N];
int l[BN],r[BN],num[N<<1],b[N<<1],sumv[BN];
void makeblock()
{
int sz=sqrt(en2),sum=1; if(!sz) sz=1;
for(;sum*sz<en2;sum++)
{
l[sum]=r[sum-1]+1;
r[sum]=sz*sum;
for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
}
l[sum]=r[sum-1]+1;
r[sum]=en2;
for(int i=l[sum];i<=r[sum];i++) num[i]=sum;
}
void Insert(const int &x){b[x]++; sumv[num[x]]++;}
void Delete(const int &x){b[x]--; sumv[num[x]]--;}
int Rank(const int &x)
{
int cnt=0;
for(int i=1;i<num[x];i++) cnt+=sumv[i];
for(int i=l[num[x]];i<x;i++) cnt+=b[i];
return cnt+1;
}
int Kth(const int &x)
{
int cnt=0;
for(int i=1;;i++)
{
cnt+=sumv[i];
if(cnt>=x)
{
cnt-=sumv[i];
for(int j=l[i];;j++)
{cnt+=b[j]; if(cnt>=x) return j;}
}
}
}
int Next(const int &x)
{
for(int i=x+1;i<=r[num[x]];i++) if(b[i]) return i;
for(int i=num[x]+1;;i++) if(sumv[i])
for(int j=l[i];;j++)
if(b[j]) return j;
}
int Pre(const int &x)
{
for(int i=x-1;i>=l[num[x]];i--) if(b[i]) return i;
for(int i=num[x]-1;;i--) if(sumv[i])
for(int j=r[i];;j--)
if(b[j]) return j;
}
void Query(const int &p)
{
if(Q[p].op==1) anss[Q[p].p]=Rank(Q[p].k);
else if(Q[p].op==2) anss[Q[p].p]=ma[Kth(Q[p].k)];
else if(Q[p].op==4) anss[Q[p].p]=ma[Pre(Q[p].k)];
else if(Q[p].op==5) anss[Q[p].p]=ma[Next(Q[p].k)];
}
int op[N];
int main()
{
R(n); R(m);
int blo=0,sz=(int)pow((double)n,2.0/3.0);
if(!sz) sz=1;
for(int i=1;i<=n;++i)
{
R(t[i].v); t[i].p=i;
if(i%sz==1||sz==1) ++blo;
num2[i]=blo;
}
en=n;
for(int i=1;i<=m;++i)
{
R(op[i]);
if(op[i]==1||op[i]==4||op[i]==5)
{
++enq; ++en;
R(Q[enq].l); R(Q[enq].r);
Q[enq].p=enq; Q[enq].op=op[i]; Q[enq].t=enc;
R(t[en].v); t[en].p=en;
}
else if(op[i]==2)
{
++enq;
R(Q[enq].l); R(Q[enq].r); R(Q[enq].k);
Q[enq].p=enq; Q[enq].op=op[i]; Q[enq].t=enc;
}
else
{
++enc; ++en;
R(CH[enc].x); R(t[en].v);
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;
}
makeblock();
memcpy(c,a,(n+1)*sizeof(int));
en=n; enc=0; enq=0;
for(int i=1;i<=m;++i)
{
if(op[i]==3)
{
++en; ++enc;
CH[enc].y=a[en]; CH[enc].z=c[CH[enc].x];
c[CH[enc].x]=a[en];
}
else
{
++enq;
if(op[i]!=2) Q[enq].k=a[++en];
}
}
sort(Q+1,Q+enq+1);
for(int i=1;i<=Q[1].t;++i)
a[CH[i].x]=CH[i].y;
for(int i=Q[1].l;i<=Q[1].r;++i) Insert(a[i]);
Query(1);
for(int i=2;i<=enq;++i)
{
if(Q[i-1].t<Q[i].t) for(int j=Q[i-1].t+1;j<=Q[i].t;++j)
{
if(CH[j].x>=Q[i-1].l&&CH[j].x<=Q[i-1].r)
{
Insert(CH[j].y);
Delete(a[CH[j].x]);
}
a[CH[j].x]=CH[j].y;
}
else for(int j=Q[i-1].t;j>Q[i].t;--j)
{
if(CH[j].x>=Q[i-1].l&&CH[j].x<=Q[i-1].r)
{
Insert(CH[j].z);
Delete(a[CH[j].x]);
}
a[CH[j].x]=CH[j].z;
}
if(Q[i].l<Q[i-1].l) for(int j=Q[i-1].l-1;j>=Q[i].l;--j) Insert(a[j]);
else for(int j=Q[i-1].l;j<Q[i].l;++j) Delete(a[j]);
if(Q[i].r<Q[i-1].r) for(int j=Q[i-1].r;j>Q[i].r;--j) Delete(a[j]);
else for(int j=Q[i-1].r+1;j<=Q[i].r;++j) Insert(a[j]);
Query(i);
}
for(int i=1;i<=enq;++i) P(anss[i]),puts("");
return 0;
}

【带修莫队】【权值分块】bzoj3196 Tyvj 1730 二逼平衡树的更多相关文章

  1. bzoj3196: Tyvj 1730 二逼平衡树 树套树

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196 题目: 3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec ...

  2. 【函数式权值分块】【分块】bzoj3196 Tyvj 1730 二逼平衡树

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define ...

  3. 【分块】bzoj3196 Tyvj 1730 二逼平衡树

    分块 或 树套树. 在每个块中维护一个有序表,查询时各种二分,全都是分块的经典操作,就不详细说了. 块的大小定为sqrt(n*log2(n))比较快. #include<cstdio> # ...

  4. 【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树

    线段树套pb_ds里的平衡树,在洛谷OJ上测试,后三个测试点TLE #include<cstdio> #include<algorithm> #include<ext/p ...

  5. [bzoj3196][Tyvj 1730][二逼平衡树] (线段树套treap)

    Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在 ...

  6. [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树

    题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...

  7. BZOJ3196: Tyvj 1730 二逼平衡树

    传送门 主席树的常数蜜汁优越,在BZOJ上跑了rnk1. 做法很简单,主席树套BIT. 1-3做法很简单,第四个和第五个做法转换成前两个就行了. //BZOJ 3196 //by Cydiater / ...

  8. 2019.01.08 bzoj3809: Gty的二逼妹子序列(莫队+权值分块)

    传送门 题意:多组询问,问区间[l,r]中权值在[a,b]间的数的种类数. 看了一眼大家应该都知道要莫队了吧. 然后很容易想到用树状数组优化修改和查询做到O(mnlogamax)O(m\sqrt nl ...

  9. POJ 2104 - 主席树 / 询问莫队+权值分块

    传送门 题目大意应该都清楚. 今天看到一篇博客用分块+莫对做了这道题,直接惊呆了. 首先常规地离散化后将询问分块,对于某一询问,将莫队指针移动到指定区间,移动的同时处理权值分块的数字出现次数(单独.整 ...

随机推荐

  1. 特殊密码锁 的通过码是:(请注意,在openjudge上提交了程序并且通过以后,就可以下载到通过码。请注意看公告里关于编程作业的说明)

    // // main.cpp // openjudge特殊密码锁 // // Created by suway on 17/11/20. // Copyright © 2017年 suway. // ...

  2. linux 学习好资源

    Linux-Wiki.cn http://linux-wiki.cn/wiki/zh-hans/Linux%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84    Linux目录 ...

  3. SQLyog 使用笔记,自增主键数据冲突错误

    select max(id) from test ; desc test ; insert into  test (a,b,c) values ('abc','123-213','test'); RE ...

  4. java web标签

    一:国庆结束了,回来上班,结果老大说过两天才出差,所以这两天就用来补自己不太懂的知识或者以前没有熟悉的知识,jsp的标签就是,因为在项目中自己封装了一些标签,但是我自己只是会用,真正的原理性的东西我还 ...

  5. 如何去掉Json字符串中反斜杠

    做项目的时候,遇到了这样的问题,前台传来的Json字符串在实体类中不对应(无法转换为实体类),而且传来的数据项是跟着数据库中的表的变动而变动的(不能重写实体类). 前台Json字符串为: string ...

  6. AOP编程的常用实现方式

    aop代理分为静态代理.jdk动态代理.cglib动态代理 通过动态代理的方式实现横向扩展,实现权限校验.日志等功能. jdk静态代理:代理类和委托类实现同一接口,并且在代理类中需要硬编码接口. jd ...

  7. 【bzoj1911-[Apio2010]特别行动队】斜率优化

    [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个段的分数的总和最大. [输入格式]  第1行:1个 ...

  8. [POJ2954&POJ1265]皮克定理的应用两例

    皮克定理: 在一个多边形中.用I表示多边形内部的点数,E来表示多边形边上的点数,S表示多边形的面积. 满足:S:=I+E/2-1; 解决这一类题可能运用到的: 求E,一条边(x1,y1,x2,y2)上 ...

  9. [bzoj3532][Sdoi2014]Lis——拆点最小割+字典序+退流

    题目大意 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若 干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案. 如果有多种方案,请输出将删去项的附加属性 ...

  10. 微信网页版的onclick事件不起作用

    我的错误是在跳转的url中拼接了url,如下: var myBaseUrl="https://xxx/"; function do() { $.ajax({ url :myBase ...