有几个点卡常数……

  发现若第一维为位置,第二维为大小,那么修改时第一维修改区间,查询时第一维查询区间,必须挂标记。而这种情况下标记很抽象,而且Push_down不是O(1)的,并不可行。
  那要怎么做呢?不妨交换一下,第一维为大小,第二维为位置,在第二维中挂标记,这样Push_down就是O(1)的了。
  做完这道题,我最大的启发就是:树套树不适于在第一维挂标记,因为标记的维度会是一维的,根本不好维护。

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <ctime>
using namespace std;
const int maxn=;
const int maxm=;
int rt[maxn*],tot,n,m;
int ch[maxm][],sum[maxm],tag[maxm]; void Push_up(int x){
sum[x]=sum[ch[x][]]+sum[ch[x][]];
} void Add(int &x,int l,int r,int d){
if(!x)x=++tot;
sum[x]+=(r-l+)*d;
tag[x]+=d;
} void Push_down(int x,int l,int r){
if(tag[x]&&l!=r){
int mid=(l+r)>>;
if(!ch[x][])ch[x][]=++tot;
if(!ch[x][])ch[x][]=++tot;
sum[ch[x][]]+=(mid-l+)*tag[x];tag[ch[x][]]+=tag[x];
sum[ch[x][]]+=(r-mid)*tag[x];tag[ch[x][]]+=tag[x];
tag[x]=;
}
} void Update(int &x,int l,int r,int a,int b){
if(!x)x=++tot;
Push_down(x,l,r);
if(l>=a&&r<=b){sum[x]+=r-l+;tag[x]+=;return;}
int mid=(l+r)>>;
if(mid>=a)Update(ch[x][],l,mid,a,b);
if(mid<b)Update(ch[x][],mid+,r,a,b);
Push_up(x);
} void Modify(int x,int l,int r,int g,int a,int b){
Update(rt[x],,n,a,b);
if(l==r)return;
int mid=(l+r)>>;
if(mid>=g)Modify(x<<,l,mid,g,a,b);
else Modify(x<<|,mid+,r,g,a,b);
} int Query(int x,int l,int r,int a,int b){
if(!x)return ;
Push_down(x,l,r);
if(l>=a&&r<=b)return sum[x];
int mid=(l+r)>>,ret=;
if(mid>=a)ret=Query(ch[x][],l,mid,a,b);
if(mid<b)ret+=Query(ch[x][],mid+,r,a,b);
return ret;
} int Solve(int l,int r,int k){
int lo=,hi=n,p=;
while(lo<hi){
int mid=(lo+hi)>>,tmp;
tmp=Query(rt[p<<],,n,l,r);
if(tmp>=k)hi=mid,p<<=;
else lo=mid+,p=p<<|,k-=tmp;
}
return hi;
} int op,a,b,c;
int main(){
#ifndef ONLINE_JUDGE
freopen("zjoi13_sequence.in","r",stdin);
freopen("zjoi13_sequence.out","w",stdout);
#endif
scanf("%d%d",&n,&m);
while(m--){
scanf("%d%d%d%d",&op,&a,&b,&c);
if(op==)Modify(,,n,n-c+,a,b);
else printf("%d\n",n-Solve(a,b,c)+);
}
//printf("%.2f\n",(double)clock()/CLOCKS_PER_SEC);
return ;
}

  然后就是喜闻乐见的整体二分,很好理解。

  有些地方没有缩行,打丑了,理论上60行足矣,这就是整体二分的威力!

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
struct Node{
int tp,l,r,k,id,tmp;
}p[maxn],tmp[maxn]; int b0[maxn],b1[maxn];
int v0[maxn],v1[maxn];
int ans[maxn],n,Q,tim,cntQ; void Add0(int x,int d){
while(x<=n){
b0[x]=v0[x]==tim?b0[x]+d:d;
v0[x]=tim;
x+=x&(-x);
}
} void Add1(int x,int d){
while(x<=n){
b1[x]=v1[x]==tim?b1[x]+d:d;
v1[x]=tim;
x+=x&(-x);
}
} void Update(int l,int r,int d){
Add0(l,d);
Add0(r+,-d);
Add1(l,-(l-)*d);
Add1(r+,r*d);
} int Query(int x){
int ret=;
for(int i=x;i;i-=i&(-i))
ret+=v0[i]==tim?b0[i]:;
ret*=x;
for(int i=x;i;i-=i&(-i))
ret+=v1[i]==tim?b1[i]:;
return ret;
} int Que(int l,int r){
return Query(r)-Query(l-);
} void Solve(int h,int t,int l,int r){
if(h>t)return;
if(l==r){
for(int i=h;i<=t;i++)
ans[p[i].id]=l;
return;
}
int mid=(l+r)>>;
int ct1=h,ct2=h;++tim;
for(int i=h;i<=t;i++){
if(p[i].tp==){
if(p[i].k>mid)continue;
Update(p[i].l,p[i].r,);
ct2+=;
}
else{
p[i].tmp=Que(p[i].l,p[i].r);
if(p[i].tmp>=p[i].k)ct2+=;
}
}
for(int i=h;i<=t;i++){
if(p[i].tp==){
if(p[i].k>mid)tmp[ct2++]=p[i];
else tmp[ct1++]=p[i];
}
else{
if(p[i].tmp>=p[i].k)tmp[ct1++]=p[i];
else p[i].k-=p[i].tmp,tmp[ct2++]=p[i];
}
}
for(int i=h;i<=t;i++)p[i]=tmp[i];
Solve(h,ct1-,l,mid);Solve(ct1,t,mid+,r);
} int main(){
#ifndef ONLINE_JUDGE
freopen("zjoi13_sequence.in","r",stdin);
freopen("zjoi13_sequence.out","w",stdout);
#endif
scanf("%d%d",&n,&Q);
for(int i=;i<=Q;i++){
scanf("%d%d",&p[i].tp,&p[i].l);
scanf("%d%d",&p[i].r,&p[i].k);
if(p[i].tp==){
p[i].id=++cntQ;
p[i].k=Que(p[i].l,p[i].r)-p[i].k+;
}
else
Update(p[i].l,p[i].r,);
} Solve(,Q,,n); for(int i=;i<=cntQ;i++)
printf("%d\n",ans[i]);
return ;
}

数据结构(树套树):ZJOI 2013 K大数查询的更多相关文章

  1. [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)

    [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...

  2. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  3. 解题:ZJOI 2013 K大数查询

    题面 树套树,权值线段树套序列线段树,每次在在权值线段树上的每棵子树上做区间加,查询的时候左右子树二分 本来想两个都动态开点的,这样能体现树套树在线的优越性.但是常数太大惹,所以外层直接固定建树了QA ...

  4. [ZJOI 2013] K大数查询

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3110 [算法] 整体二分 + 线段树 时间复杂度 : O(NlogN ^ 2) [代 ...

  5. [BZOJ 3110] [ZJOI 2013] K大数查询

    Description 有 \(N\) 个位置,\(M\) 个操作.操作有两种,每次操作如果是: 1 a b c:表示在第 \(a\) 个位置到第 \(b\) 个位置,每个位置加入一个数 \(c\): ...

  6. 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 &amp; 3236 [Ahoi2013] 作业 题解

    [原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 978  Solved: 476 Descri ...

  7. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

  8. ZJOI2013 K大数查询 和 LG3380【模板】二逼平衡树(树套树)

    K大数查询 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c:如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的 ...

  9. BZOJ 3110 k大数查询 & 树套树

    题意: 有n个位置,每个位置可以看做一个集合,现在要求你实现一个数据结构支持以下功能: 1:在a-b的集合中插入一个数 2:询问a-b集合中所有元素的第k大. SOL: 调得火大! 李建说数据结构题能 ...

随机推荐

  1. Java_Activiti5_菜鸟也来学Activiti5工作流_之初识常用服务类和数据表(二)

    /** * 代码清单中使用 ProcessEngines类加载默认的流程配置文件(activiti.cfg.xml),再获取各个服务组件的实例. * RepositoryService主要用于管理流程 ...

  2. StringHelper类,内容截取,特别适合资讯展示列表

    public class StringHelper    {        /// <summary>        /// 截字符串        /// </summary> ...

  3. 利用SQLiteOpenHelper创建数据库,进行增删改查操作

    Android中提供SQLiteOpenHelper类,在该类的构造器中,调用Context中的方法创建并打开一个指定名称的数据库对象.继承和扩展SQLiteOpenHelper类主要做的工作就是重写 ...

  4. 如何通过WiFi来进行Android的真机模拟

    我们知道,在使用模拟机模拟的时候会出现较多的问题,所以如果有一部Android手机的话进行真机模拟是极好的. 准备工作: 第一种方法:使用数据线,具体操作百度.略(非WIFI操作的真机模拟) 第二方法 ...

  5. angular.js 简单的表达式

    <!doctype html> <html> <head> <meta charset ="utf-8"> <script s ...

  6. SGU 249.Matrix(Gray码)

    题意: 用0到2^(n+m-1)这2^(n+m-1)个数填在一个2^n*2^m的矩阵里,使得所有相邻的数的二进制表示只有一位不同. Solution: Gray码.对于第i行第j列的数,由i的Gray ...

  7. Java学习笔记——动态代理

    所谓动态,也就是说这个东西是可变的,或者说不是一生下来就有的.提到动态就不得不说静态,静态代理,个人觉得是指一个代理在程序中是事先写好的,不能变的,就像上一篇"Java学习笔记——RMI&q ...

  8. 『重构--改善既有代码的设计』读书笔记----Introduce Foreign Method

    当你无法获得一个类的源代码或者没有权限去修改这个类的时候,你对于这种为你服务的类,你可能会出现需要别的需求的时候,比如一个Date类,你需要能够让他本身直接返回出他的后一天的对象,但他没有,这个时候你 ...

  9. css去除webkit内核的默认样式

    做移动端的朋友应该知道,iphone的默认按钮是个很恶心的圆角,select下拉框也有默认样式无法修改. 这时候可以用到 -webkit-appearance:none //去除默认样 在按钮和sel ...

  10. CSS lib

    Yahoo的轻型CSS框架Pure来加速web开发 http://purecss.io/buttons/#