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

 #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. Sublime Text怎么在切分两行视口内显示同一个文件

    原文链接:http://devlog.en.alt-area.org/?p=1098 How to split one file into two views in Sublime Text2 You ...

  2. NSISの堆栈操作

    一 .堆栈 堆栈是 NSIS 维护的一堆数据,你可以根据需要往堆栈中存入任意大小的数据(as big as you like),所以你可以向堆栈中推入或读取数据,堆栈只有一个,堆栈遵守 LIFO (后 ...

  3. python学习笔记七 初识socket(进阶篇)

    socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...

  4. 流镜像(华为S9306和S5700)

    流镜像是指将设备.端口或者VLAN内收.发的指定类型报文复制到观察端口上,监控设备只对指定类型报文进行监测. 流镜像有基于ACL和基于MQC(即复杂流分类)两种配置方式.前者配置简便,但是没有后者支持 ...

  5. Linux的加密认证功能以及openssl详解

    一.详细介绍加密.解密技术 现在的加密/解密技术主要有三种:对称加密,非对称加密,和单向加密 这三种加密解密技术的组合就是现在电子商务的基础,它们三个有各自最适合的领域,而且所要完成的功能也是不同的, ...

  6. [问题2014S10] 解答

    [问题2014S10]  解答 先证明一个简单的引理. 引理  设 \(\lambda_0\) 是 \(n\) 阶方阵 \(A\) 的特征值, 则对任意的正整数 \(k\), Jordan 块 \(J ...

  7. 。Java注意事项

  8. Flex 文本控件实现自定义复制粘贴

    由于添加了自定义右键菜单,导致Textinput控件默认的右键复制粘贴功能被屏蔽了.最后通过JS脚本实现这个功能,参考代码如下 <?xml version="1.0" enc ...

  9. 关于OPencv版本不符合,相关库变化问题

    由于OPencv发展迅速,已经省略了很多原来的库文件,奈何自己才疏学浅,所以只能把OPencv 1.0中的相关版本中的库文件一直过去. 链接: http://pan.baidu.com/s/1qY1Z ...

  10. WCF双向通信,心跳

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)Q  Q:408365330     E-Mail:egojit@qq.com WCF中双程 ...