线段树+lazy标记 2019年8月10日计蒜客联盟周赛 C.小A的题
题目链接:https://nanti.jisuanke.com/t/40852
题意:给定一个01串s,进行m次操作,|s|<=1e6,m<=5e5
操作有两种
l r 0,区间[l,r]升序排序
l r 1,区间[l,r]降序排序
输出m次操作后的串s
官方解析:
维护区间1的个数,区间0的个数=区间长度-区间1的个数,完成区间赋值操作并更新即可。
个人思路:
线段树的操作都是log(n),如果带了lazy标记,就可以小于log(n),不必查询到每个点。例如将[1,3]都置为1,只用将t[2]=3即可。
另外tag是标记升序降序的lazy标记,在update和getsum中会进行标记下放。
时间复杂度小于O(m*log(|S|))

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxl=1e6+;
const int manx=5e5+;
char s[maxl];
int t[maxl*],tag[maxl*];
inline int read()
{
int f=,x=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=(x<<)+(x<<)+s-'';s=getchar();}
return x*f;
} void build(int x,int l,int r)//t[x]记录1的个数
{
tag[x]=-;
if(l==r)
{
t[x]=s[l]-'';
return;
}
int mid=(l+r)/;
build(x*,l,mid);
build(x*+,mid+,r);
t[x]=t[x*]+t[x*+]; //x<<1|1
}
int getsum(int x,int l,int r,int L,int R) //L R是要求的sum区间
{
if(l==L&&r==R)return t[x];
int mid=(l+r)/;
if(tag[x]!=-)
{
tag[x*]=tag[x*+]=tag[x];
t[x*]=tag[x]?(mid-l+):;
t[x*+]=tag[x]?(r-mid):;
tag[x]=-;
}
if(R<=mid)return getsum(x*,l,mid,L,R);
else if(L>mid)return getsum(x*+,mid+,r,L,R);
else return getsum(x*,l,mid,L,mid)+getsum(x*+,mid+,r,mid+,R);
}
void update(int x,int l,int r,int L,int R,int v)
{
if(l==L&&r==R)
{
tag[x]=v;
t[x]=v?(r-l+):;
return;
}
int mid=(l+r)/;
if(tag[x]!=-)
{
tag[x*]=tag[x*+]=tag[x];
t[x*]=tag[x]?(mid-l+):;
t[x*+]=tag[x]?(r-mid):;
tag[x]=-;
}
if(R<=mid) update(x*,l,mid,L,R,v);
else if(L>mid) update(x*+,mid+,r,L,R,v);
else
{
update(x*,l,mid,L,mid,v);
update(x*+,mid+,r,mid+,R,v);
}
t[x]=t[x*]+t[x*+];
}
void dfs(int x,int l,int r)
{
if(l==r)
{
printf("%d",t[x]);
return;
}
int mid=(l+r)/;
if(tag[x]!=-)
{
tag[x*]=tag[x*+]=tag[x];
t[x*]=tag[x]?(mid-l+):;
t[x*+]=tag[x]?(r-mid):;
tag[x]=-;
}
dfs(x*,l,mid);
dfs(x*+,mid+,r);
}
int main()
{
scanf("%s",s+);
int n=strlen(s+);
build(,,n);
int m=read();
int u,v,w;
while(m--)
{
u=read();v=read();w=read(); //[u,v],w=0升序,w=1降序
int sum=getsum(,,n,u,v); //算出有几个1
if(sum==||sum==(v-u+))continue;
if(w==)update(,,n,u,v-sum,),update(,,n,v-sum+,v,);
else update(,,n,u,u+sum-,),update(,,n,u+sum,v,);
}
dfs(,,n);
return ;
}
另:移位符号计算比*号快,线段树要开四倍空间
线段树+lazy标记 2019年8月10日计蒜客联盟周赛 C.小A的题的更多相关文章
- 并查集 2019年8月10日计蒜客联盟周赛 K.数组
题目链接:https://nanti.jisuanke.com/t/40860 题意:给一个长度为n的数组a[],n<1e5,a[i]<1e5 三个操作: 1 x y:把所有值为x的数据改 ...
- poj3468 线段树+lazy标记
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 92921 ...
- POJ3237 Tree(树剖+线段树+lazy标记)
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbe ...
- HDU_1698 Just a Hook(线段树+lazy标记)
pid=1698">题目请点我 题解: 接触到的第一到区间更新,须要用到lazy标记.典型的区间着色问题. lazy标记详情请參考博客:http://ju.outofmemory.cn ...
- POJ 3225 线段树+lazy标记
lazy写崩了--. 查了好久 /* U-> [l,r]–>1 I-> [1,l-1] [r+1,+无穷] –>0 D-> [l,r]–>0 C-> [1,l ...
- 线段树+Lazy标记(我的模版)
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ...
- C++-POJ2777-Count Color[线段树][lazy标记][区间修改]
分析:https://www.bilibili.com/read/cv4777102 #include <cstdio> #include <algorithm> using ...
- 线段树lazy标记??Hdu4902
Nice boat Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- 2019年3月10日 装饰器进阶-模拟session
ser_dic={'username':None,'login':False}#用户字典,反应登入状态,用字典做全局变量 def idf(func):#验证登入信息是否正确 def wrapper(* ...
随机推荐
- redis 底层数据结构
简单动态字符串SDS 包含字符串长度,剩余可用长度,字符数组 用于Redis中所有的string存储 字典(map) 数组+链表形式,跟hashMap很像 链地址法解决hash冲突 rehash使用新 ...
- PowerMock学习(三)之Mock局部变量
编写powermock用例步骤: 类上面先写这两个注解@RunWith(PowerMockRunner.class).@PrepareForTest(StudentService.class) 先模拟 ...
- Pashmak and Buses(构造)
题目链接:http://codeforces.com/problemset/problem/459/C 题意:n个人, k辆车, d天,每天将所有 任意人安排到k辆车, 问怎样安排, 可时不存在 2人 ...
- 逆向libbaiduprotect(二)
首先要确保你所使用的gdb和gdbserver是配对的,最好(或必须)是sdk内相同platform(api level)下的gdb和gdbserver.否则你使用的gdb可能与运行测试机上的gdbs ...
- Ubuntu Server16.04 安装Odoo11
odoo11采用了python3实现的. 1.sudo adduser odoo //新建一个用户odoo 2.给odoo 用户root 权限 visudo //使用visudo 编辑 /et ...
- Java——内部类详解
说起内部类,大家肯定感觉熟悉又陌生,因为一定在很多框架源码中有看到别人使用过,但又感觉自己使用的比较少,今天我就带你具体来看看内部类. 内部类基础 所谓内部类就是在类的内部继续定义其他内部结构类. 在 ...
- 原创|我是如何从零学习开发一款跨平台桌面软件的(Markdown编辑器)
原始冲动 最近一直在学习 Electron 开发桌面应用程序,目的是想做一个桌面编辑器,虽然一直在使用Typore这款神器,但无奈Typore太过国际化,在国内水土不服,无法满足我的一些需求. 比如实 ...
- Jrebel 激活的方法
jrebel 激活的方法: 试了很多都不好用,下面这个方法比较简单快捷.(不知道可以坚持多久) myjrebel 7月分官方正式停用,致使广大朋友无法使用jrebel/XRebel,可按如下地址进行 ...
- 小程序取消IOS虚拟支付解决方案
前因 本来我们的小程序用的好好的,结果突然有一天,微信就把小程序的ios端的虚拟支付给关了...坑爹啊!搞的安卓端的可以支付,ios的支付不了.于是就在网上找解决办法. 一说通过app跳转支付,总不能 ...
- Netty学习篇⑥--ByteBuf源码分析
什么是ByteBuf? ByteBuf在Netty中充当着非常重要的角色:它是在数据传输中负责装载字节数据的一个容器;其内部结构和数组类似,初始化默认长度为256,默认最大长度为Integer.MAX ...