首页 > 其他分享 >P4344 [SHOI2015] 脑洞治疗仪——线段树

P4344 [SHOI2015] 脑洞治疗仪——线段树

时间:2024-10-21 21:48:34浏览次数:7  
标签:10 P4344 位置 脑洞 SHOI2015 区间 quad 治疗仪

[SHOI2015] 脑洞治疗仪

题目描述

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

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

1      0      1      0      0      0      1      1      1      0

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

例如,用上面第 \(8\) 号位置到第 \(10\) 号位置去修补第 \(1\) 号位置到第 \(4\) 号位置的脑洞,我们就会得到:

1      1      1      1      0      0      1      0      0      0

如果再用第 \(1\) 号位置到第 \(4\) 号位置去修补第 \(8\) 号位置到第 \(10\) 号位置:

0      0      0      0      0      0      1      1      1      1

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

如果再用第 \(7\) 号位置到第 \(10\) 号位置去填补第 \(1\) 号位置到第 \(6\) 号位置:

1      1      1      1      0      0      0      0      0      0

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

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

输入格式

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

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

  • \(0\quad l\quad r\):SHTSC 挖了一个范围为 \([l, r]\) 的脑洞。
  • \(1\quad l_0\quad r_0\quad l_1\quad r_1\):SHTSC 进行了一次脑洞治疗,用从 \(l_0\) 到 \(r_0\) 的脑组织修补 \(l_1\) 到 \(r_1\) 的脑洞。
  • \(2\quad l\quad r\):SHTSC 询问 \([l, r]\) 区间内最大的脑洞有多大。

上述区间均在 \([1, n]\) 范围内。

输出格式

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

样例 #1

样例输入 #1

10 10
0 2 2
0 4 6
0 10 10
2 1 10
1 8 10 1 4
2 1 10
1 1 4 8 10
2 1 10
1 7 10 1 6
2 1 10

样例输出 #1

3
3
6
6

提示

对于 \(20\%\) 的数据,\(n, m \leq 100\);
对于 \(50\%\) 的数据,\(n, m \leq 20000\);
对于 \(100\%\) 的数据,\(n, m \leq 200000\)。

分析

我们发现,本题中的操作较为简单:

操作一:区间覆盖——区间改为0。

操作二:区间查询+区间覆盖——先查询 $ [l0,r0] $ 1的个数\(num\),在 $ [l1,r1] $ 中二分找到第一个能把 $num $ 个1全部填入的末尾位置,区间改为1。

操作三:区间查询——仿照最大子段和,我们定义 $ s[i].mxval $ 为最长的0区间,$ s[i].lsum $ 为从区间左端开始的最长0区间,$ s[i].rsum $ 同理,合并一下即可。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
inline int read()
{
    register char c=getchar();
    int x=0;
    while(!isdigit(c))c=getchar();
    while(isdigit(c)){x=(x<<1)+(x<<3)+c-48;c=getchar();}
    return x;
}
int n,m;
struct segtree
{
    int l,r,val;
    int lsum,rsum,mxval;
    int tag,siz;
}s[N<<2];

void build(int i,int l,int r)
{
    s[i].l=l;s[i].r=r;
    s[i].siz=s[i].val=r-l+1;
    s[i].tag=-1;
    if(l==r)return ;
    int mid=(l+r)>>1;
    build(i<<1,l,mid);build(i<<1|1,mid+1,r);
}

inline void pushup(segtree &a,segtree &lc,segtree &rc)
{
    a.val=lc.val+rc.val;
    a.lsum=lc.lsum;
    if(lc.val==0)a.lsum+=rc.lsum;
    a.rsum=rc.rsum;
    if(rc.val==0)a.rsum+=lc.rsum;
    a.mxval=max( max( lc.mxval,rc.mxval ) ,
                lc.rsum+rc.lsum);
}

inline void pushtag(int i,int z)
{
    s[i].tag=z;
    s[i].val=z*s[i].siz;
    s[i].mxval=s[i].lsum=s[i].rsum=s[i].siz-s[i].val;
}

inline void pushdown(int i)
{
    if(s[i].tag==-1)return ;
    pushtag(i<<1,s[i].tag);
    pushtag(i<<1|1,s[i].tag);
    s[i].tag=-1;
}

inline void upd(int i,int x,int y,int z)//turn range[x,y] 0/1
{
    if( (s[i].val==0 && z==0) || (s[i].val==s[i].siz && z==1) )return ;
    if(s[i].l>=x && s[i].r<=y)
    {
        pushtag(i,z);
        return ;
    }
    pushdown(i);
    int mid=(s[i].l+s[i].r)>>1;
    if(x<=mid)upd(i<<1,x,y,z);
    if(y>mid)upd(i<<1|1,x,y,z);
    pushup(s[i],s[i<<1],s[i<<1|1]);
}

inline int que(int i,int x,int y)//query the 1 in range[x,y]
{
    if(s[i].val==0)return 0;
    if(s[i].l>=x && s[i].r<=y)
        return s[i].val;
    pushdown(i);
    int mid=(s[i].l+s[i].r)>>1,sum=0;
    if(x<=mid)sum+=que(i<<1,x,y);
    if(y>mid)sum+=que(i<<1|1,x,y);
    return sum;
}

inline void eq(segtree &a,segtree &b)//a <-- b
{
    a.val=b.val;
    a.mxval=b.mxval;
    a.lsum=b.lsum;
    a.rsum=b.rsum;
}

segtree ask(int i,int x,int y)//query the longest 0 range in range[x,y]
{
    if(s[i].l>=x && s[i].r<=y)
        return s[i];
    pushdown(i);
    int mid=(s[i].l+s[i].r)>>1;
    segtree lc,rc,sum;
    bool f1=0,f2=0;
    if(x<=mid){f1=1;lc=ask(i<<1,x,y);}
    if(y>mid){f2=1;rc=ask(i<<1|1,x,y);}
    if(f1 && f2)
        pushup(sum,lc,rc);
    else if(f1) eq(sum,lc);
    else eq(sum,rc);
    return sum;
}

void work()
{
    n=read();m=read();
    build(1,1,n);
    while(m--)
    {
        int opt,l,r,x,y;
        opt=read();l=read();r=read();
        if(opt==1)//use [l,r] to fix [x,y]
        {
            x=read();y=read();
            int all=que(1,l,r);
            upd(1,l,r,0);
            int L=x,R=y,mid=0,pos=-1;
            while(L<=R)
            {
                mid=(L+R)>>1;
                if(mid-x+1-que(1,x,mid)<=all)
                    pos=mid,L=mid+1;
                else R=mid-1;
            }
            if(pos>=x)
                upd(1,x,pos,1);
        }
        else if(opt==2)
        {
            int ans=ask(1,l,r).mxval;
            printf("%d\n",ans);
        }
        else
            upd(1,l,r,0);
    }
}
int main()
{
    work();
    return 0;
}

标签:10,P4344,位置,脑洞,SHOI2015,区间,quad,治疗仪
From: https://www.cnblogs.com/Glowingfire/p/18490952

相关文章

  • P4343 [SHOI2015] 自动刷题机(最详细版本 通俗易懂)
    题目背景曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机——一种可以自动AC题目的神秘装置。题目描述自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序。每秒,自动刷题机的代码生成模块会有两种可能的结果:1.写了 x 行代码2......
  • 【SHOI2015】自动刷题机
    一道朴素的二分题,二分的基础很不好所以选择了这道本道题主要进行二分的考察容易发现,对于给定的序列,n越大能过的题是越少的,所以可以二分来求刚好过k道题的左右边界。若mid大于k,即做得太多了,就将l右移。若mid小于k,即做得太少了,就将r左移。代码实现:#include<bits/stdc++.h>u......
  • P4345 [SHOI2015] 超能粒子炮·改 题解
    P4345[SHOI2015]超能粒子炮·改题解求\[\sum_{i=0}^k\binom{n}{i}\pmod{2333}\]思路这种模数小的组合数计数问题可以考虑Lucas定理,试试呗。如果按余数分类不好优化,可以按商分类求和,这样一来套个前缀和可以得到一个递推式,注意最后一块商可能是不整的,单独拿出来即可。......
  • 进行一个脑洞治疗仪的保存
    #include<iostream>#include<fstream>#include<algorithm>//#defineintlonglongusingnamespacestd;structnode_t{ intl,r; intlval,rval,val; intsum,tag;#definel(x)tr[x].l#definer(x)tr[x].r#definelval(x)tr[x].lval#de......
  • 脑洞治疗仪
    P4344[SHOI2015]脑洞治疗仪翻译题目\(0\quadl\quadr\):区间置\(0\)。\(1\quadl_0\quadr_0\quadl_1\quadr_1\):将\([l_0,r_0]\)中的\(1\)取出,填到\([l_1,r_1]\)(从左到右填入,多出去的扔掉)。\(2\quadl\quadr\),查询区间内最大连续\(0\)的长度。思路我们......
  • P4344 SHOI2015 脑洞治疗仪
    \(P4344\)[\(SHOI2015\)]脑洞治疗仪一、题目描述曾经发明了自动刷题机的发明家\(SHTSC\)又公开了他的新发明:脑洞治疗仪——一种可以治疗他因为发明而日益增大的脑洞的神秘装置。为了简单起见,我们将大脑视作一个\(01\)序列。\(1\)代表这个位置的脑组织正常工作,\(0\)代表......
  • P4343 [SHOI2015]自动刷题机
    https://www.luogu.com.cn/problem/P4343 #include<iostream>usingnamespacestd;constintN=1e5+2;#defineintlonglongconstintinf=1e15;inta[N],n......
  • BZOJ 4592 [Shoi2015]脑洞治疗仪
    题目链接:​​传送门​​​Description曾经发明了自动刷题机的发明家SHTSC又公开了他的新发明:脑洞治疗仪–一种可以治疗他因为发明而日益增大的脑洞的神秘装置。为了简单起......