题目链接: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的题的更多相关文章

  1. 并查集 2019年8月10日计蒜客联盟周赛 K.数组

    题目链接:https://nanti.jisuanke.com/t/40860 题意:给一个长度为n的数组a[],n<1e5,a[i]<1e5 三个操作: 1 x y:把所有值为x的数据改 ...

  2. poj3468 线段树+lazy标记

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 92921   ...

  3. 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 ...

  4. HDU_1698 Just a Hook(线段树+lazy标记)

    pid=1698">题目请点我 题解: 接触到的第一到区间更新,须要用到lazy标记.典型的区间着色问题. lazy标记详情请參考博客:http://ju.outofmemory.cn ...

  5. POJ 3225 线段树+lazy标记

    lazy写崩了--. 查了好久 /* U-> [l,r]–>1 I-> [1,l-1] [r+1,+无穷] –>0 D-> [l,r]–>0 C-> [1,l ...

  6. 线段树+Lazy标记(我的模版)

    #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ...

  7. C++-POJ2777-Count Color[线段树][lazy标记][区间修改]

     分析:https://www.bilibili.com/read/cv4777102 #include <cstdio> #include <algorithm> using ...

  8. 线段树lazy标记??Hdu4902

    Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) To ...

  9. 2019年3月10日 装饰器进阶-模拟session

    ser_dic={'username':None,'login':False}#用户字典,反应登入状态,用字典做全局变量 def idf(func):#验证登入信息是否正确 def wrapper(* ...

随机推荐

  1. win7/win10系列的office安装与激活

    Windows系列电脑安装office傻瓜式教程 一.    下载与安装 下载 (1).所需工具:迅雷 下载链接:http://xl9.xunlei.com/ 显示界面如下,点击“立即下载”即可,然后 ...

  2. Java自学基础、进阶、项目实战网站推荐

    推荐一个自学的好平台,有Java基础,前端,后端,基础的内容都有讲解,还有框架的讲解和实战项目,特别适合自学 JAVA 自学网站 JAVA 练习题 Spring 教程 Mybatis 教程 Sprin ...

  3. Servlet相关学习

    Servlet入门解析 概念 运行在服务器端的小程序 servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则 实现servlet接口.复写方法 快速入门 创建web项目 ...

  4. Mysql 开启远程连接服务

    Mysql 开启远程连接服务 修改要远程访问的那个用户的 host 为 % use mysql; insert into user (host, user, password) values('%', ...

  5. nyoj 115-城市平乱 (BFS)

    115-城市平乱 内存限制:64MB 时间限制:1000ms 特判: No 通过数:5 提交数:8 难度:4 题目描述: 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维 ...

  6. Linux入门之安装及相关知识。

    一.VMware虚拟机安装与使用 1.1.VMware 简介 VMware是一个虚拟PC的软件,可以在现有的操 作系统上虚拟出一个新的硬件环境,相当于模拟 出一台新的PC.以此来实现在一台机器上真正 ...

  7. 力扣(LeetCode)两整数之和 个人题解

    不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a .b ​​​​​​​之和. 示例 1: 输入: a = 1, b = 2 输出: 3 示例 2: 输入: a = -2, b = ...

  8. php Swoole实现毫秒级定时任务

    项目开发中,如果有定时任务的业务要求,我们会使用linux的crontab来解决,但是它的最小粒度是分钟级别,如果要求粒度是秒级别的,甚至毫秒级别的,crontab就无法满足,值得庆幸的是swoole ...

  9. ubuntukylin16.04LTS(乌班图麒麟版长期支持版,并非银河麒麟)安装体验

    最近,国产银河麒麟版在政府部门推广使用.我有幸接触了,感觉还是不错的.这次政府软件正版化整改中,也列入了windows和银河麒麟的选项.我想试安装一下,可是没找到.就近找了它的类似系统ubuntuky ...

  10. think PHP 查询、更改

    最近公司没有什么新项目,故准备搞搞PHP,正好后端有一些小东西需要搞一下,我就来试试吧. PHP 基于think PHP 3 实现功能: 1.为销售绑定虚拟号码分组(查询可以绑定的分组 -> 绑 ...