【LOJ#3146】[APIO2019]路灯(树套树)

题面

LOJ

题解

考场上因为\(\text{bridge}\)某个\(\text{subtask}\)没有判\(n=1\)的情况导致我卡了\(3.5h\)左右,然后这题就只能匆匆\(rush\)了一个\(60\)分暴力......


考虑维护出每一个时刻的亮的灯的连续段,那么对于连续段\([l,r]\),显然此时刻在区间内的任意一组询问都会被产生贡献。

因为维护连续段非常不好处理,所以考虑每一个未开灯的地方的影响。

假设\(x\)位置未开灯,上一个没有开的位置是\(lt\),那么对于左区间在\([lt+1,i]\),右区间在\([lt+1,i]\)的范围内就会产生贡献,那么我们可以把区间换成点,于是贡献变成了二维数点。

那么直接拿树套树维护就行了。(或者\(CDQ\)之类也行)

这里统计答案用类似差分的方法,我们一开始把所有位置都给上\(+Q\)的贡献,对于依次修改操作,把影响的区间的贡献给补上就好了。

举个例子,还是\(x\)和\(lt\)两个位置,那么左区间在\([lt+1,i]\),右区间在\([i+1,n+1]\)的区间没有贡献。

那么给\((lt+1,i+1)\)位置加上一个\(-Q\),\((i+1,i+1)\)位置加上一个\(Q\)就可以维护出这个贡献了。

最后统计答案的时候要记得如果答案当前恰好还是一个完整区间,就要把剩下不要统计时间的\(Q\)个时间给去掉。。。

#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
#define MAX 300300
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,Q;
struct Node{int ls,rs,v;}t[MAX<<6];
int tot,rt[MAX];
void Modify(int &x,int l,int r,int p,int w)
{
if(!x)x=++tot;t[x].v+=w;
if(l==r)return;
int mid=(l+r)>>1;
if(p<=mid)Modify(t[x].ls,l,mid,p,w);
else Modify(t[x].rs,mid+1,r,p,w);
}
int Query(int x,int l,int r,int L,int R)
{
if(!x)return 0;
if(L<=l&&r<=R)return t[x].v;
int mid=(l+r)>>1,ret=0;
if(L<=mid)ret+=Query(t[x].ls,l,mid,L,R);
if(R>mid)ret+=Query(t[x].rs,mid+1,r,L,R);
return ret;
}
int lb(int x){return x&(-x);}
void Modify(int x,int y,int v){while(x<=n+1)Modify(rt[x],1,n+1,y,v),x+=lb(x);}
int Query(int x,int y){int s=0;while(x)s+=Query(rt[x],1,n+1,1,y),x-=lb(x);return s;}
set<int> S;set<int>::iterator it,pr,nt;
char ch[MAX];
int main()
{
n=read();Q=read();scanf("%s",ch+1);
S.insert(0);S.insert(n+1);Modify(1,1,Q);
for(int i=1,j=0;i<=n;++i)
{
if(ch[i]=='1')continue;
S.insert(i);
Modify(j+1,i+1,-Q);
Modify(i+1,i+1,Q);
j=i;
}
while(Q--)
{
char opt[8];scanf("%s",opt);
if(opt[0]=='t')
{
int x=read(),zt=(ch[x]=='0')?1:-1;
if(ch[x]=='1')S.insert(x);
it=S.find(x);
pr=nt=it;--pr;++nt;
Modify(*pr+1,x+1,Q*zt);Modify(x+1,x+1,-Q*zt);
if(*nt!=n+1)Modify(*pr+1,*nt+1,-Q*zt),Modify(x+1,*nt+1,Q*zt);
if(ch[x]=='0')S.erase(x);
ch[x]^=1;
}
else
{
int x=read(),y=read();
printf("%d\n",Query(x,y)-Q*(S.lower_bound(x)==S.lower_bound(y)));
}
}
return 0;
}

【LOJ#3146】[APIO2019]路灯(树套树)的更多相关文章

  1. P5445 [APIO2019]路灯(树套树)

    P5445 [APIO2019]路灯 转化为平面上的坐标(x,y),set维护连续区间. 用树套树维护矩阵加法,单点查询. 注意维护矩阵差分的时候, $(x,y,v)$是对$(x,y)(n+1,n+1 ...

  2. 【APIO2019】路灯(ODT & (树套树 | CDQ分治))

    Description 一条 \(n\) 条边,\(n+1\) 个点的链,边有黑有白.若结点 \(a\) 可以到达 \(b\),需要满足 \(a\to b\) 的路径上的边不能有黑的.现给出 \(0\ ...

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

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

  4. BZOJ4170 极光(CDQ分治 或 树套树)

    传送门 BZOJ上的题目没有题面-- [样例输入] 3 5 2 4 3 Query 2 2 Modify 1 3 Query 2 2 Modify 1 2 Query 1 1 [样例输出] 2 3 3 ...

  5. bzoj3262: 陌上花开(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  6. bzoj3295: [Cqoi2011]动态逆序对(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

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

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

  8. BZOJ 3110 树套树 && 永久化标记

    感觉树套树是个非常高深的数据结构.从来没写过 #include <iostream> #include <cstdio> #include <algorithm> ...

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

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

随机推荐

  1. oidc hybrid flow 与另外两种模式的异同

    很多学习identityserver的文章都没有解释清楚oidc hybrid混合模式的含义.本文将解释hybrid模式与另外两种模式的主要区别. 我们先看一下一手文档: https://openid ...

  2. oracle学习笔记(八)——结果集元数据ResultSetMetaData以及ResultSet转为对应的实体类框架

    介绍 可用于获取关于 ResultSet 对象中列的类型和属性信息的对象,在持久框层框架(如:mybatis, hibernate)中被广泛的应用. 常用方法 int getColumnCount() ...

  3. wpf button style IsMouseOver

    <Style x:Key="workButtonStyle" TargetType="{x:Type Button}"> <Style.Tri ...

  4. ASP.NET MVC IOC依赖注入之Autofac系列开篇

    Autofac为IOC组件,实现控制反转,主要结合面向接口编程,完成较大程度的解耦工作. 使用IOC,必须面向接口编程,所谓的面向接口编程,即程序中依赖于抽象,而不依赖于具体实现. 需要所有的业务逻辑 ...

  5. Python爬取上交所一年大盘数据

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 半个码农2018 PS:如有需要Python学习资料的小伙伴可以加点 ...

  6. centOS服务器安装mongodb

    1.为服务器添加mongodb的包管理工具,这就相当于在windows中安装npm,以便能用npm安装各种依赖.添加了这个包管理工具,才能在后面对mongodb做一系列操作. touch /etc/y ...

  7. bayaim_hadoop 开篇 0.0

    ------------------bayaim_hadoop 开篇 0.0 -----2018年11月19日09:21:46--------------------------------- 前言: ...

  8. TICK技术栈(一)TICK技术栈介绍

    1.什么是TICK技术栈? 1.1 简介 TICK 是由 InfluxData开发的一套开源工具栈,由 Telegraf, InfluxDB, Chronograf, Kapacitor 四个工具的首 ...

  9. Python入门基础学习(列表/元组/字典/集合)

    Python基础学习笔记(二) 列表list---[ ](打了激素的数组,可以放入混合类型) list1 = [1,2,'请多指教',0.5] 公共的功能: len(list1) #/获取元素 lis ...

  10. react中antd的表格自定义展开

    antd的表格官方案例中给出的都是固定的图表展开,在做需求的时候,需要使用点击最后一列,然后出现展开内容,实现效果图如下 在最开始设置一个全局变量 const keys = [];在设置列参数的函数中 ...