题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3110

第一道线段树套线段树!

第一道标记永久化!

为什么为什么写了两个半小时啊……

本想线段树套平衡树,但想不出怎么合并不同区间上的平衡树(LCT??)。

于是看了一下Zinn的TJ。原来是线段树套线段树呀。原来外层是权值内层是区间呀。原来要动态开点呀。

  这是因为区间线段树要下传标记什么的,而权值线段树在本题中都是在叶子上修改。所以这样比较方便。

然后手胡了一番pshp,pshd。RE到飞起。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=5e4,M=1e5+;
int n,m,tt1,tt2,rtt,rt[M<<],ls[M<<],rs[M<<],L,R;
struct Node{
int ls,rs;long long lazy,sum;//ll!
}a[N*+];//每个外层点上有logn个节点
void pshd2(int cr,int &l,int &r,int lb,int rb)
{
if(!l)l=++tt2;if(!r)r=++tt2;//!!
if(!a[cr].lazy)return;
int w=a[cr].lazy,mid=lb+rb>>;
a[cr].lazy=;a[l].lazy+=w;a[r].lazy+=w;
a[l].sum+=w*(mid-lb+);a[r].sum+=w*(rb-mid);
}
void pshp2(int cr)
{
a[cr].sum=a[a[cr].ls].sum+a[a[cr].rs].sum;
}
void pshp1(int &cr,int p1,int p2)
{
if(!cr)cr=++tt2;
a[cr].sum=a[p1].sum+a[p2].sum;
a[cr].lazy=a[p1].lazy+a[p2].lazy;
if(a[p1].ls||a[p2].ls)pshp1(a[cr].ls,a[p1].ls,a[p2].ls);
if(a[p1].rs||a[p2].rs)pshp1(a[cr].rs,a[p1].rs,a[p2].rs);
}
void mdfy(int l,int r,int &cr)
{
if(!cr)cr=++tt2;
if(l>=L&&r<=R){a[cr].sum+=(r-l+);a[cr].lazy++;return;}//r-l+1!!
pshd2(cr,a[cr].ls,a[cr].rs,l,r);int mid=l+r>>;
if(L<=mid)mdfy(l,mid,a[cr].ls);
if(mid<R)mdfy(mid+,r,a[cr].rs);
pshp2(cr);
}
void mdfy(int l,int r,int &cr,int p)
{
if(!cr)cr=++tt1;
if(l==r){mdfy(,n,rt[cr]);return;}
int mid=l+r>>;
if(p<=mid)mdfy(l,mid,ls[cr],p);
else mdfy(mid+,r,rs[cr],p);
pshp1(rt[cr],rt[ls[cr]],rt[rs[cr]]);
//别pshp了,标记永久化
}
int query(int l,int r,int cr)
{
// printf("l=%d r=%d L=%d R=%d a[%d].sum=%d\n",l,r,L,R,cr,a[cr].sum);
if(l>=L&&r<=R)return a[cr].sum;
pshd2(cr,a[cr].ls,a[cr].rs,l,r);int mid=l+r>>;
if(L>mid)return query(mid+,r,a[cr].rs);
if(R<=mid)return query(l,mid,a[cr].ls);
return query(l,mid,a[cr].ls)+query(mid+,r,a[cr].rs);
}
int query(int l,int r,int cr,int k)
{
if(l==r)return l;
int mid=l+r>>;
int w=query(,n,rt[rs[cr]]);
// printf("l=%d r=%d mid=%d w=%d\n",l,r,mid,w);
if(w>=k)return query(mid+,r,rs[cr],k);
else return query(l,mid,ls[cr],k-w);
}
int main()
{
scanf("%d%d",&n,&m);int op,c;
while(m--)
{
scanf("%d%d%d%d",&op,&L,&R,&c);
if(op==)
mdfy(-N,N,rtt,c);
else
printf("%d\n",query(-N,N,rtt,c));
}
return ;
}

然后又看看Zinn的TJ。原来是标记永久化呀。抄抄抄。

标记永久化就是没有pshp和pshd。在修改的时候往下走的时候就把sum改掉(因为改sum需要知道区间大小,所以需要传L,R),不往下走的时候同样打上lazy。在查询的时候把路径上的lazy累加。细节是累加的lazy需要乘上目标区间的大小,而且因为这种写法,打lazy的时候就不能加sum了。

仍旧数组大小迷茫中。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=5e4+,M=N*;//
int n,m,tt1,tt2,lm,rtt,ls[N<<],rs[N<<],rt[N<<],lss[M],rss[M];
int L,R,op[N],x[N],y[N],c[N],tp[N];
ll sum[M],lazy[M];//ll,防止计算时爆int
void add(int l,int r,int &cr,int L,int R)//传L,R
{
if(!cr)cr=++tt2;
if(l==L&&r==R){lazy[cr]++;return;}//==
sum[cr]+=R-L+;//打了lazy就不要加sum了--看query那里
int mid=l+r>>;
if(mid<L)add(mid+,r,rss[cr],L,R);
else if(mid>=R)add(l,mid,lss[cr],L,R);
else add(l,mid,lss[cr],L,mid),add(mid+,r,rss[cr],mid+,R);
}
void insert(int l,int r,int &cr,int p)
{
if(!cr)cr=++tt1;
add(,n,rt[cr],L,R);
if(l==r)return;int mid=l+r>>;
if(p<=mid)insert(l,mid,ls[cr],p);
else insert(mid+,r,rs[cr],p);
}
//int query(int l,int r,int cr,ll lz)
//{
// if(l>=L&&r<=R)return sum[cr]+lz;
// int mid=l+r>>1;int ret=0;
// if(L<=mid)ret+=query(l,mid,lss[cr],lz+lazy[cr]);
// if(mid<R)ret+=query(mid+1,r,rss[cr],lz+lazy[cr]);
// return ret;
//}
ll query(int l,int r,int cr,int L,int R)//传L,R
{
if(!cr)return ;///////
ll ret=(R-L+)*lazy[cr];//可以每次return加ret,就不用传参数
if(l==L&&r==R)return ret+sum[cr];
int mid=l+r>>;
if(L>mid)return ret+query(mid+,r,rss[cr],L,R);
if(R<=mid)return ret+query(l,mid,lss[cr],L,R);
return ret+query(l,mid,lss[cr],L,mid)+query(mid+,r,rss[cr],mid+,R);//仔细想想只加一个ret!!!
}
int query(int l,int r,int &cr,int k)
{
if(!cr)cr=++tt1;//
if(l==r)return l;
ll w=query(,n,rt[rs[cr]],L,R),mid=l+r>>;
if(w>=k)return query(mid+,r,rs[cr],k);
else return query(l,mid,ls[cr],k-w);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d%d",&op[i],&x[i],&y[i],&c[i]);
if(op[i]==)tp[++lm]=c[i];//only op==1!!!
}
sort(tp+,tp+m+);lm=unique(tp+,tp+m+)-tp-;
for(int i=;i<=m;i++)
{
L=x[i];R=y[i];
if(op[i]==)
{
int tmp=lower_bound(tp+,tp+lm+,c[i])-tp;
insert(,lm,rtt,tmp);
}
else printf("%d\n",tp[query(,lm,rtt,c[i])]);
}
return ;
}

bzoj 3110 [Zjoi2013]K大数查询——线段树套线段树(标记永久化)的更多相关文章

  1. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  2. BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 418   Solved: 235 [ Submit][ ...

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

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

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

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

  5. BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )

    BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...

  6. BZOJ 3110 [Zjoi2013]K大数查询(整体二分)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 11654  Solved: 3505[Submit][St ...

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

    题目链接: BZOJ - 3110 题目分析 这道题是一道树套树的典型题目,我们使用线段树套线段树,一层是区间线段树,一层是权值线段树.一般的思路是外层用区间线段树,内层用权值线段树,但是这样貌似会很 ...

  8. bzoj 3110 [Zjoi2013]K大数查询(树套树)

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

  9. BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)

    题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...

随机推荐

  1. input 不显示输入的历史记录

    第一次在 input 输入后,下次就会自动显示输入历史记录,去掉这种默认效果的解决方案 <input name="username" type="text" ...

  2. selenium学习笔记——driver.get(url) 页面加载时间太长

    # 两个同时设置才行 # 实现效果:加载状态停止,进行代码下一步操作 driver.set_page_load_timeout(10) driver.set_script_timeout(10) # ...

  3. Android开发 WebView的详解

    前言 WebView 是Android显示html内容的主要方式,当然TextView也可以加载html内容.但是WebView除了功能更加强大,最重要的是还能调用Html里的JavaScript语言 ...

  4. 深入理解Java虚拟机(类文件结构)

    深入理解Java虚拟机(类文件结构) 欢迎关注微信公众号:BaronTalk,获取更多精彩好文! 之前在阅读 ASM 文档时,对于已编译类的结构.方法描述符.访问标志.ACC_PUBLIC.ACC_P ...

  5. apache tomcat 一个网站多域名的实现方法

    因此处是进行多域名设置,所以 Apache 与 tomcat的结合没有详述,此处只是设置多域名的方法 windows下 C:\WINDOWS\system32\drivers\etc 文件夹内 hos ...

  6. vue的无缝滚动插件vue-seamless-scroll的使用

    https://chenxuan0000.github.io/component-document/index_prod.html#/component/seamless-others 在vue环境下 ...

  7. Composer的简介说明与安装

    https://mp.weixin.qq.com/s/aSZRhoa2-JjKOTRVhPdxdQ Composer 是 PHP 的一个依赖管理工具.它允许你申明项目所依赖的代码库,它会在你的项目中为 ...

  8. PAT甲级——A1075 PAT Judge

    The ranklist of PAT is generated from the status list, which shows the scores of the submissions. Th ...

  9. QC的安装和配置

    QC(Quality center)的安装配置 Wmware 虚拟机 数据库SQL server2000 Windows server 2003 须安装数据库的sp4补丁包 注意事项 数据库安装时选择 ...

  10. 记一次log4j日志文件小事故

    最近散仙在做公司的一个跟搜索有关的数据分析项目,主要就是统计搜索的转化率,目的主要有以下几个: (1)通过数据分析挖掘,找出搜索业务在整个平台系统里的GMV里所占份额 (2)给公司的搜索算法调优,提供 ...