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

 #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. BooleanToVisibilityConverter.cs

    //---------------------------------------------------------------------------- // // Copyright (C) M ...

  2. 2015年江西理工大学C语言程序设计竞赛(高级组)

    A 解法:DP+二分 dp[i]=max(dp[i],dp[j]+p[i].v)(i>j) dp[i]表示建立i点之后能够获得的最大值 int n,M; struct node { int l, ...

  3. [转]unicode,ansi,utf-8,unicode big endian的故事

    unicode,ansi,utf-8,unicode big endian的故事很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的 ...

  4. ArrayBlockingQueue

    ArrayBlockingQueue是阻塞队列的一种,基于数组实现,长度固定,队尾添加,队首获取, 构造函数: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font ...

  5. 151102SQL语句

    $condition = array($pk=>array('in',explode(',',$id)));//??? $this->model->where($condition) ...

  6. win7 用户目录

    robocopy "C:\Users" "D:\Users" /E /COPYALL /XJ /XD "C:\Users\Administrator& ...

  7. 如何设置WIN10任务栏

    1.鼠标右键点击任务栏 然后点击锁定任务栏,去掉前面的钩 2.然后鼠标右击任务栏 选择工具栏 点击新建工具栏 3.打开后点击新建文件夹,可以重命名,然后选择刚才新建的文件夹 4.此时任务栏就有了 5. ...

  8. day5 -指针

    指针和指针变量 指针就是地址,地址就是指针 地址就是存放单元的编号 指针变量是存放地址的变量 指针和指针变量是两个不同的概念,但是要注意,通常我们叙述时会把指针变量简称为指针,实际他们含义并不一样 指 ...

  9. 【CSU1812】三角形和矩形 【半平面交】

    检验半平面交的板子. #include <stdio.h> #include <bits/stdc++.h> using namespace std; #define gg p ...

  10. MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)

    前面讲了模态对话框和非模态对话框,本节来将一种特殊的对话框--属性页对话框. 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过标签切换各个页面 ...