【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. mysql 5.7 创建用户报错ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value

    如: INSERT INTO user (host, user, authentication_string, select_priv, insert_priv, update_priv) VALUE ...

  2. MySQL for OPS 09:MHA + Atlas 实现读写分离高可用

    写在前面的话 前面做了 MHA 高可用,但是存在这样一个问题,我们花了 4 台机器,但是最终被利用起来的也就一台,主库.这样硬件利用率才 25%,这意味着除非发生故障,不然其他几台机器都是摆设.明显的 ...

  3. Jsp学习笔记(2)——页面导航、表单、EL表达式

    页面导航 有两种跳转页面的方法.重定向和请求转发 两者区别: 请求转发(forward) 重定向(rerect) 请求服务次数 1 2 是否保留第一次请求request范围的属性 保留 不保留 地址栏 ...

  4. vs未能正确加载CSharpPackage包,未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包

    VS2017打开项目时提示未能正确加载CSharpPackage包, 可以使用 devenv命令工具来解决,操作如下 打开vs2017开发人员命令提示符(请使用管理员身份运行),如图 敲入  deve ...

  5. C#中巧用Lambda进行数据的筛选查询等处理

    场景 有一个Record对象的list,如果要根据其某个属性CycleIndex进行分组,类似于sql的group by分组查询. 如果要在这个这个list中查找出符合某种条件的数据,类似于sql的w ...

  6. sqlserver 问题来了,视图不会自动更新,如果是用*创建的

    奇葩问题一个 create view时候用的select * 关联了几个表创建的. 后修改select *  的表,结果悲剧了. select * from 视图得到的结果绝对让你想哭.不报错,不提示 ...

  7. css横屏问题的设置

    <link rel="stylesheet" media="all and (orientation:portrait)" href="css/ ...

  8. 概要设计文档(final)

    1. 引言部分 引言部分主要说明编写目的.系统的范围和参考资料等. 1.1目的 该文档的目的是描述“自习吧”微信小程序的概要设计,主要内容包括系统功能简介.系统结构设计.模块设计和界面设计等. 本文档 ...

  9. 源码包安装转换rpm包

    目录 纯净版虚拟机 1. 先安装个虚拟机,登陆nginx官网 http://nginx.org/选择一个稳定的版本 2. 右键复制地址,到新克隆的纯净虚拟机wget 下载 3.源码包 4.解压 tar ...

  10. js 判断当前时间是否处于某个一个时间段内

    js 判断当前时间(或者所选时间)是否在某一时间段 我们可以使用 jutils - JavaScript常用函数库的 isDuringDate 函数来实现 传入 beginDateStr (开始时间) ...