感觉树套树是个非常高深的数据结构。从来没写过

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define LL long long
using namespace std;
const LL Maxm=;
const LL Maxn=;
const LL T=;
struct OPERATOR
{
LL Type,a,b,c;
}Operator[Maxm];
LL Sum[Maxn*T],ls[Maxn*T],rs[Maxn*T],Addv[Maxn*T],sz=,V[Maxm],Root[Maxn*];
LL n,m,H;
inline void Get_Int(LL &x)
{
x=; register char ch=getchar(); LL f=;
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();} x*=f;
}
inline void Put_Int(LL x)
{
char ch[]; register int top=;
if (x==) ch[++top]='';
while (x) ch[++top]=x%+'',x/=;
while (top) putchar(ch[top--]); putchar('\n');
}
//=================================================================
inline void Push_Down(LL o,LL p,LL q)
{
if (!ls[o]) ls[o]=++sz;
if (!rs[o]) rs[o]=++sz;
LL l=ls[o],r=rs[o];
if (Addv[o])
{
Addv[l]+=Addv[o];
Addv[r]+=Addv[o];
LL mid=(p+q)>>;
Sum[l]+=(mid-p+)*Addv[o];
Sum[r]+=(q-mid)*Addv[o];
Addv[o]=;
}
}
inline void Push_Up(LL o) {Sum[o]=Sum[ls[o]]+Sum[rs[o]];}
void Add_Num(LL &o,LL l,LL r,LL p,LL q)
{
if (o==) o=++sz;
if (l==p && r==q)
{
Sum[o]+=(q-p+);
Addv[o]++;
return;
}
Push_Down(o,l,r);
LL mid=(l+r)>>;
if (q<=mid) Add_Num(ls[o],l,mid,p,q);
if (p>=mid+) Add_Num(rs[o],mid+,r,p,q);
if (p<=mid && q>=mid+)
Add_Num(ls[o],l,mid,p,mid),Add_Num(rs[o],mid+,r,mid+,q);
Push_Up(o);
}
void Update(LL o,LL l,LL r,LL p,LL q,LL c)
{
Add_Num(Root[o],,n,p,q);
if (l==r) return;
LL mid=(l+r)>>;
if (c<=mid) Update(o<<,l,mid,p,q,c);
if (c>=mid+) Update(o<<|,mid+,r,p,q,c);
}
//======================================== LL Get_Sum(LL o,LL l,LL r,LL p,LL q)
{
if (!o) return ;
if (p==l && r==q) return Sum[o];
LL mid=(l+r)>>;
Push_Down(o,l,r);
if (q<=mid) return Get_Sum(ls[o],l,mid,p,q);
if (p>=mid+) return Get_Sum(rs[o],mid+,r,p,q);
if (p<=mid && q>=mid+) return Get_Sum(ls[o],l,mid,p,mid)+Get_Sum(rs[o],mid+,r,mid+,q);
} LL Query(LL o,LL l,LL r,LL p,LL q,LL k)
{
LL ret=Get_Sum(Root[o<<],,n,p,q);
if (l==r) return l;
LL mid=(l+r)>>;
if (k<=ret) return Query(o<<,l,mid,p,q,k);
if (k>=ret+) return Query(o<<|,mid+,r,p,q,k-ret);
} int main()
{
Get_Int(n),Get_Int(m); LL cnt=;
for (int i=;i<=m;i++)
{
Get_Int(Operator[i].Type);
Get_Int(Operator[i].a),Get_Int(Operator[i].b),Get_Int(Operator[i].c);
if (Operator[i].Type==) V[++cnt]=Operator[i].c;
}
sort(V+,V+cnt+);
H=unique(V+,V+cnt+)-(V+);
for (int i=;i<=m;i++)
{
if (Operator[i].Type==) Update(,,H,Operator[i].a,Operator[i].b,H-(lower_bound(V+,V+H+,Operator[i].c)-V)+);
if (Operator[i].Type==) Put_Int(V[H-Query(,,H,Operator[i].a,Operator[i].b,Operator[i].c)+]);
}
return ;
}

C++

加了标记永久化以后

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define LL long long
using namespace std;
const LL Maxm=;
const LL Maxn=;
const LL T=;
struct OPERATOR
{
LL Type,a,b,c;
}Operator[Maxm];
LL Sum[Maxn*T],ls[Maxn*T],rs[Maxn*T],Addv[Maxn*T],sz=,V[Maxm],Root[Maxn*];
LL n,m,H;
inline void Get_Int(LL &x)
{
x=; register char ch=getchar(); LL f=;
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();} x*=f;
}
inline void Put_Int(LL x)
{
char ch[]; register int top=;
if (x==) ch[++top]='';
while (x) ch[++top]=x%+'',x/=;
while (top) putchar(ch[top--]); putchar('\n');
}
//=================================================================
void Add_Num(LL &o,LL l,LL r,LL p,LL q)
{
if (o==) o=++sz;
Sum[o]+=(q-p+);
if (l==p && r==q)
{
Addv[o]++;
return;
}
if (!ls[o]) ls[o]=++sz;
if (!rs[o]) rs[o]=++sz;
LL mid=(l+r)>>;
if (q<=mid) Add_Num(ls[o],l,mid,p,q);
if (p>=mid+) Add_Num(rs[o],mid+,r,p,q);
if (p<=mid && q>=mid+)
Add_Num(ls[o],l,mid,p,mid),Add_Num(rs[o],mid+,r,mid+,q);
}
void Update(LL o,LL l,LL r,LL p,LL q,LL c)
{
Add_Num(Root[o],,n,p,q);
if (l==r) return;
LL mid=(l+r)>>;
if (c<=mid) Update(o<<,l,mid,p,q,c);
if (c>=mid+) Update(o<<|,mid+,r,p,q,c);
}
//======================================== LL Get_Sum(LL o,LL l,LL r,LL p,LL q,LL pos)
{
if (!o) return ;
if (p==l && r==q) return Sum[o]+pos*(r-l+);
LL mid=(l+r)>>;
if (!ls[o]) ls[o]=++sz;
if (!rs[o]) rs[o]=++sz;
if (q<=mid) return Get_Sum(ls[o],l,mid,p,q,pos+Addv[o]);
if (p>=mid+) return Get_Sum(rs[o],mid+,r,p,q,pos+Addv[o]);
if (p<=mid && q>=mid+) return Get_Sum(ls[o],l,mid,p,mid,pos+Addv[o])+Get_Sum(rs[o],mid+,r,mid+,q,pos+Addv[o]);
} LL Query(LL o,LL l,LL r,LL p,LL q,LL k)
{
LL ret=Get_Sum(Root[o<<],,n,p,q,);
if (l==r) return l;
LL mid=(l+r)>>;
if (k<=ret) return Query(o<<,l,mid,p,q,k);
if (k>=ret+) return Query(o<<|,mid+,r,p,q,k-ret);
} int main()
{
// freopen("sequence.in","r",stdin);
// freopen("sequence.out","w",stdout);
Get_Int(n),Get_Int(m); LL cnt=;
for (int i=;i<=m;i++)
{
Get_Int(Operator[i].Type);
Get_Int(Operator[i].a),Get_Int(Operator[i].b),Get_Int(Operator[i].c);
if (Operator[i].Type==) V[++cnt]=Operator[i].c;
}
sort(V+,V+cnt+);
H=unique(V+,V+cnt+)-(V+);
for (int i=;i<=m;i++)
{
if (Operator[i].Type==) Update(,,H,Operator[i].a,Operator[i].b,H-(lower_bound(V+,V+H+,Operator[i].c)-V)+);
if (Operator[i].Type==) Put_Int(V[H-Query(,,H,Operator[i].a,Operator[i].b,Operator[i].c)+]);
}
return ;
}

C++

直接20s卡时,加了标记永久化之后18s,还是很慢!

BZOJ 3110 树套树 && 永久化标记的更多相关文章

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

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

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

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

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

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

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

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

  5. bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】

    树套树: 约等于是个暴力了.以区间线段树的方式开一棵权值线段树,在权值线段树的每一个点上以动态开点的方式开一棵区间线段树. 结果非常惨烈(时限20s) #include<iostream> ...

  6. BZOJ 3110 [Zjoi2013]K大数查询 ——树套树

    [题目分析] 外层区间线段树,内层是动态开点的权值线段树. SY神犇说树套树注重的是内外层的数据结构的选择问题,果然很重要啊. 动态开点的实现方法很好. [代码] #include <cstdi ...

  7. [BZOJ 3489] A simple rmq problem 【可持久化树套树】

    题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...

  8. bzoj 1901: Zju2112 Dynamic Rankings(树套树)

    1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...

  9. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

随机推荐

  1. netbeans中给jpanl添加背景图片制定代码的理解——匿名内部类继承父类

    此测试是为了仿照在netbeans中给jpanl添加背景图片的制定代码的执行过程 在JpDemo中定义了个Car类的数据类型,但在给其赋值对象时使用了匿名内部类,继承了Car类,是其子类,并重写了父类 ...

  2. 修改mysql表结构,添加一个主键索引自增字段,修改原来的主字段为普通字段

    原来有一个字段id,为自增,主键,索引.现在要新增一个字段s_id为自增,主键,索引.同时把原来的主字段改成普通字段,默认值为0. Alter table e_diamond_jhds change ...

  3. prototype与原型链

    1.今天翻看 阮一峰老师的博客看到了,一篇讲javascript为什么要设计出prototype,跳转      大意就是new 的方式有缺陷,没有共同的属性,一下明白了很多. 在来一张原型链的图:

  4. Hosts文件的使用

    hosts文件是什么?在哪里?hosts文件:系统文件,可以记事本打开并编辑.一般用于域名到ip地址的解析.当用户在浏览器中输入网络的域名时,系统首先会自动从hosts文件中找到对应的ip地址,一旦找 ...

  5. centos7 Nexus maven私有仓库

    cd /home wget http://www.sonatype.org/downloads/nexus-latest-bundle.tar.gz mkdir nexus tar zxvf nexu ...

  6. A replacement solution to using Google Drive in Ubuntu

    Grive2 Get dependencies You need to get the dependency libraries along with their development (-dev ...

  7. 原生cookie

    出于浏览器的安全性限制,从WEB应用程序中访问用户本地文件系统是有许多限制的.但是WEB站点的开发人员可以使用cookie,将少量信息保存在用户本地硬盘的指定空间中. document对象的cooki ...

  8. 基础笔记5(file)

    file 可以是目录和文件(只是是java程序与系统的文件进行一种关联) File file1 = new File("f:/mytest", "test5.txt&qu ...

  9. requestAnimationFrame 动画

    requestAnimationFrame : 调用这个方法,就是告诉浏览器要执行动画了,从而浏览器自动计算动画时间间隔,从而在恰当的时候刷新UI, 动画更加平滑. 他的用法和setTimeout() ...

  10. ASP.NET 配置KindEditor文本编辑器

    ASP.NET 配置KindEditor文本编辑器 跟着这篇博客做了两个小时,只搞出了下面这么个东西. 时间浪费在了原博客里这样的一句话:将kindeditor/asp.net/bin/LitJSON ...