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

 #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. 模块(序列化(json&pickle)+XML+requests)

    一.序列化模块 Python中用于序列化的两个模块: json     跨平台跨语言的数据传输格式,用于[字符串]和 [python基本数据类型] 间进行转换 pickle   python内置的数据 ...

  2. Java垃圾回收以及内存分配

    http://www.cnblogs.com/ggjucheng/p/3977384.html http://www.blogjava.net/qcyycom/archive/2012/04/14/3 ...

  3. 基于cmake编译安装MySQL-5.5

    cmake的重要特性之一是其独立于源码(out-of-source)的编译功能,即编译工作可以在另一个指定的目录中而非源码目录中进行,这可以保证源码目录不受任何一次编译的影响,因此在同一个源码树上可以 ...

  4. 深入理解CSS网页布局-理论篇

    在CSS网页开发布局中,需要对浮动和定位有深刻的理解才能在开发中游刃有余. 基于此,在博客园中做了本篇总结,这些总结来自实践经验和阅读一些书籍后的理解总结,主要内容为浮动,清除浮动,定位. (可点击屏 ...

  5. IE的条件注释

    <!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--> <!--[if IE]> 所有的IE可识别 <![ ...

  6. iOS开发数据库篇—SQLite的应用

    iOS开发数据库篇—SQLite的应用 一.简单说明 在iOS中使用SQLite3,首先要添加库文件libsqlite3.dylib和导入主头文件. 导入头文件,可以使用库中的函数(是纯C语言的) 二 ...

  7. Flex 学习笔记 ComboBox内容框宽度

    如何设置ComboBox下拉选项框的宽度呢 左边下拉框发现字符太长了   属性里也找不到相关宽度可以设置,解决如下 <!--添加open事件 打开下拉选项框时设置--> <s:Com ...

  8. Beginning Windows Azure Development Guide

    目  录 一 初始化Windows Azure 二 云应用程序的编写. 2.1云应用程序的创建. 2.2一个简单的云应用程序. 2.3 托管云程序. 三 云程序的数据库操作. 3.1通过Cloud平台 ...

  9. python去除空格和换行符的方法

    一.去除空格 strip() " xyz ".strip() # returns "xyz" " xyz ".lstrip() # retu ...

  10. 中国Linux源镜像站大全

    原文链接:http://www.centoscn.com/yunwei/news/2012/1227/131.html 一.国内的linux源镜像站点: 1.企业源:阿里云开源镜像站: http:// ...