题目描述:

曾经发明了自动刷题机的发明家 SHTSC 又公开了他的新发明:脑洞治疗仪——一种可以治疗他因为发明而日益增大的脑洞的神秘装置。

为了简单起见,我们将大脑视作一个 01 序列。11代表这个位置的脑组织正常工作,00代表这是一块脑洞。

                                                      

脑洞治疗仪修补某一块脑洞的基本工作原理就是将另一块连续区域挖出,将其中正常工作的脑组织填补在这块脑洞中。(所以脑洞治疗仪是脑洞的治疗仪?)

例如,用上面第88号位置到第1010号位置去修补第11号位置到第44号位置的脑洞,我们就会得到:

                                                      

如果再用第11号位置到第44号位置去修补第88号位置到第1010号位置:

                                                      

这是因为脑洞治疗仪会把多余出来的脑组织直接扔掉。

如果再用第77号位置到第1010号位置去填补第11号位置到第66号位置:

                                                      

这是因为如果新脑洞挖出来的脑组织不够多,脑洞治疗仪仅会尽量填补位置比较靠前的脑洞。

假定初始时 SHTSC 并没有脑洞,给出一些挖脑洞和脑洞治疗的操作序列,你需要即时回答 SHTSC 的问题:在大脑某个区间中最大的连续脑洞区域有多大。

输入输出格式

输入格式:

第一行两个整数 n、m,表示 SHTSC 的大脑可分为从1到n编号的n个连续区域,有m个操作。

以下m行每行是下列三种格式之一:

0 l r:SHTSC 挖了一个范围为[l,r]的脑洞。

1 $l_0$ $r_0$ $l_1$ $r_1$:SHTSC 进行了一次脑洞治疗,用从$l_0$ 到$r_0$ 的脑组织修补$l_1$到$r_1$ 的脑洞。

2 $l$ $r$:SHTSC 询问$[l,r]$区间内最大的脑洞有多大。

上述区间均在$[1,n]$范围内。

输出格式:

对于每个询问,输出一行一个整数,表示询问区间内最大连续脑洞区域有多大。

思路

很多题解都提到了GSS系列的最大连续子段和问题,那我就不说了,我只说这道题中我用到的一些奇妙的解法

1.反着定义

这道题要求的是最大连续0的长度,那么用最大子段和的话如果你按1走统计的就不是0,而是1,我们可以将1定义为-inf,0定义为1,再跑最大子段和即可

2.分开存

gss中要存一个区间和sum,但由于上面的定义形式,这玩意儿显然不能表示0(或1)的数量,我们可以用一个mix,专门存0或1的数量

大体思路:

0.首先,给1节点打上-inf的lazy标记,表示没有脑洞

1.对于0操作,区间覆盖,打lazy标记后直接修改即可

2.对于2操作,GSS标准查询即可

3.对于1操作,先求出l1,r1的脑组织数,再全挖成脑洞,之后填进l2,r2去即可(函数写成int式,优先填左区间,填完后返回剩余脑洞数)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define rij register int j
#define rs 262144
#define int long long
using namespace std;
struct tree{
long long lmax,rmax,sum,lazy,maxn,mix;
}x[];
int n,m,p;
void pushdown(int nl,int nr,long long val,int bh)
{
int mid=(nl+nr)/;
long long cd=mid-nl+;
x[bh*].lazy=val;
x[bh*].lmax=val*cd;
x[bh*].rmax=val*cd;
x[bh*].sum=val*cd;
x[bh*].maxn=val*cd;
x[bh*].mix=(val%)*cd;
x[bh*+].mix=(val%)*cd;
x[bh*+].lazy=val;
x[bh*+].lmax=val*cd;
x[bh*+].rmax=val*cd;
x[bh*+].sum=val*cd;
x[bh*+].maxn=val*cd;
x[bh].lazy=;
}
void fg(int l,int r,int nl,int nr,int bh)
{
if(l<nl)
{
l=nl;
}
if(r>nr)
{
r=nr;
}
if(x[bh].lazy==)
{
return;
}
if(x[bh].lazy==-)
{
pushdown(nl,nr,x[bh].lazy,bh);
}
if(l==nl&&r==nr)
{
x[bh].lazy=;
x[bh].sum=(r-l+);
x[bh].lmax=(r-l+);
x[bh].rmax=(r-l+);
x[bh].maxn=(r-l+);
x[bh].mix=(r-l+);
return;
}
int mid=(nl+nr)/;
if(l<=mid)
{
fg(l,r,nl,mid,bh*);
}
if(r>=mid+)
{
fg(l,r,mid+,nr,bh*+);
}
x[bh].mix=x[bh*].mix+x[bh*+].mix;
x[bh].sum=x[bh*].sum+x[bh*+].sum;
x[bh].lmax=max(x[bh*].lmax,x[bh*].sum+x[bh*+].lmax);
x[bh].rmax=max(x[bh*+].rmax,x[bh*+].sum+x[bh*].rmax);
x[bh].maxn=max(x[bh*].maxn,max(x[bh*+].maxn,x[bh*].rmax+x[bh*+].lmax));
}
int sum(int l,int r,int nl,int nr,int bh)
{
if(l<nl)
{
l=nl;
}
if(r>nr)
{
r=nr;
}
if(l==nl&&r==nr)
{
return x[bh].mix;
}
if(x[bh].lazy!=&&nl!=nr)
{
pushdown(nl,nr,x[bh].lazy,bh);
}
int mid=(nl+nr)/;
int ans=;
if(l<=mid)
{
ans+=sum(l,r,nl,mid,bh*);
}
if(r>=mid+)
{
ans+=sum(l,r,mid+,nr,bh*+);
}
return ans;
}
int add(int l,int r,int nl,int nr,int sl,int bh)
{
if(l<nl)
{
l=nl;
}
if(r>nr)
{
r=nr;
}
if(x[bh].lazy!=)
{
pushdown(nl,nr,x[bh].lazy,bh);
}
if(l==nl&&r==nr&&sl>=(r-l+))
{
sl-=x[bh].mix;
x[bh].mix=;
x[bh].lmax=(-)*(r-l+);
x[bh].rmax=(-)*(r-l+);
x[bh].maxn=(-)*(r-l+);
x[bh].sum=(-)*(r-l+);
x[bh].lazy=-;
return sl;
}
int mid=(nl+nr)/;
if(l<=mid&&sl!=)
{
sl=add(l,r,nl,mid,sl,bh*);
}
if(r>=mid+&&sl!=)
{
sl=add(l,r,mid+,nr,sl,bh*+);
}
x[bh].mix=x[bh*].mix+x[bh*+].mix;
x[bh].sum=x[bh*].sum+x[bh*+].sum;
x[bh].lmax=max(x[bh*].lmax,x[bh*].sum+x[bh*+].lmax);
x[bh].rmax=max(x[bh*+].rmax,x[bh*+].sum+x[bh*].rmax);
x[bh].maxn=max(x[bh*].maxn,max(x[bh*+].maxn,x[bh*].rmax+x[bh*+].lmax));
return sl;
}
tree query(int l,int r,int nl,int nr,int bh)
{
tree an,bn;
if(l<nl)
{
l=nl;
}
if(r>nr)
{
r=nr;
}
if(x[bh].lazy!=)
{
pushdown(nl,nr,x[bh].lazy,bh);
}
if(nl==l&&nr==r)
{
an=x[bh];
return an;
}
int ltt=(nl+nr)/;
if(l<=ltt&&r<=ltt)
{
return an=query(l,r,nl,ltt,bh*);
}
if(r>ltt&&l>ltt)
{
return bn=query(l,r,ltt+,nr,bh*+);
}
else
{
an=query(l,r,nl,ltt,bh*);
bn=query(l,r,ltt+,nr,bh*+);
an.maxn=max(an.maxn,max(bn.maxn,an.rmax+bn.lmax));
an.lmax=max(an.lmax,an.sum+bn.lmax);
an.rmax=max(bn.rmax,bn.sum+an.rmax);
an.sum=an.sum+bn.sum;
return an;
}
}
signed main()
{
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
scanf("%lld%lld",&n,&m);
x[].lazy=-;
for(rii=;i<=m;i++)
{
int l,r;
scanf("%lld",&p);
if(p==)
{
scanf("%lld%lld",&l,&r);
fg(l,r,,rs,);
}
if(p==)
{
scanf("%lld%lld",&l,&r);
tree ans=query(l,r,,rs,);
if(ans.maxn<)
{
ans.maxn=;
}
printf("%lld\n",ans.maxn);
}
if(p==)
{
int l1,l2,r1,r2;
scanf("%lld%lld%lld%lld",&l2,&r2,&l1,&r1);
int ltt=sum(l2,r2,,rs,);
ltt=(r2-l2+)-ltt;
fg(l2,r2,,rs,);
if(ltt>(r2-l2+))
{
ltt=r2-l2+;
}
add(l1,r1,,rs,ltt,);
}
}
}

【SHOI2015】脑洞治疗仪(恶心的线段树,区间最大子段和)的更多相关文章

  1. 【BZOJ4592】[Shoi2015]脑洞治疗仪 线段树

    [BZOJ4592][Shoi2015]脑洞治疗仪 Description 曾经发明了自动刷题机的发明家SHTSC又公开了他的新发明:脑洞治疗仪--一种可以治疗他因为发明而日益增大的脑洞的神秘装置. ...

  2. 【题解】Luogu P4344 [SHOI2015]脑洞治疗仪

    原题传送门:P4344 [SHOI2015]脑洞治疗仪 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 珂朵莉树好题啊 我一开始一直Re65 后来重构代码就ac了,或许是rp问题 ...

  3. 「模板」 线段树——区间乘 && 区间加 && 区间求和

    「模板」 线段树--区间乘 && 区间加 && 区间求和 原来的代码太恶心了,重贴一遍. #include <cstdio> int n,m; long l ...

  4. POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】

    任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  5. POJ 2823 Sliding Window 线段树区间求和问题

    题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...

  6. CF444C. DZY Loves Colors[线段树 区间]

    C. DZY Loves Colors time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)

    http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便, ...

  8. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  9. HDU 1698 Just a Hook(线段树 区间替换)

    Just a Hook [题目链接]Just a Hook [题目类型]线段树 区间替换 &题解: 线段树 区间替换 和区间求和 模板题 只不过不需要查询 题里只问了全部区间的和,所以seg[ ...

  10. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

随机推荐

  1. 【Linux】安装配置Tomcat7

    第一步:下载Tomcat安装包 下载地址:https://tomcat.apache.org/download-70.cgi [root@localhost ~]# wget http://mirro ...

  2. PAT 1056 Mice and Rice

    #include <cstdio> #include <climits> #include <cstdlib> #include <vector> #i ...

  3. typeScript入门(一)构建环境和数据类型

    最近入坑v-cli 3.0,发现ts越来越常用了,于是开始入坑学习. 1.构建ts环境 npm install -g typescript Mac和vscode用户可以用以下方式构建tsdemo项目 ...

  4. Android自定义之ScrollView下拉刷新

    公司项目,需要用到ScrollView的下拉刷新,一开始使用的时候PullToRefresh三方库的下拉刷新,我比较纠结第三档库,很强大,但是,公司项目的需求,PullToRefresh就不能做到了, ...

  5. Tcpdump usage examples

    In most cases you will need root permission to be able to capture packets on an interface. Using tcp ...

  6. 【Leetcode】【Easy】Palindrome Number

    Determine whether an integer is a palindrome. Do this without extra space. 判断一个整数是不是回文整数(例12321).不能使 ...

  7. jQuery 资料

    jQuery 元素选择器 jQuery 使用 CSS 选择器来选取 HTML 元素. $("p") 选取 <p> 元素. $("p.intro") ...

  8. March 30 2017 Week 13 Thursday

    I learned the value of hard work by working hard. 只有真的努力了,才会知道努力的价值. On the day, March 12th 2017, I ...

  9. March 10 2017 Week 10 Friday

    If you love life, life will love you back. 爱生活,生活也会爱你. Love life, and it will love you back. All thi ...

  10. SAP成都研究院许聚龙:Hello, Coresystems!

    Jerry的前一篇文章<SAP成都研究院数字创新空间沟通S/4HANA和C/4HANA的智能服务演示视频和Coresystems分享预告>已经提到,接下来会由SAP成都研究院数字创新空间的 ...