• [SHOI2015]脑洞治疗仪


    洛谷题目链接

    珂朵莉树吼啊!!!

    对于操作$0$,其实就是区间赋值为$0$的操作,直接套模板就行了

    对于操作$1$,应该是这个题目最难的操作了(虽然还是很简单),我们先查询$(l_0,r_0)$这个区间的$1$的数量,最后扫一遍$(l_1,r_1)$这个区间,如果$1$的数量够的话直接更改区间值,如果不够的话就把其中够的那块区间赋值就行了,详细看代码

    对于操作$2$,直接模板查询就行了

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #define Set set<Node>::iterator
    #define N 200007
    using namespace std;
    struct Node
    {
    	int l,r;
    	mutable int val;
    	Node(int L,int R,int V):l(L),r(R),val(V){}
    	Node(int L):l(L){}
    	bool operator<(const Node &it)const
    	{
    		return l<it.l;
    	}
    };
    set<Node> st;
    int n,m;
    Set Split(int x)
    {
    	Set it=st.lower_bound(Node(x));
    	if(it!=st.end()&&it->l==x)
    		return it;
    	--it;
    	int L=it->l,R=it->r,V=it->val;
    	st.erase(it);
    	st.insert(Node(L,x-1,V));
    	return st.insert(Node(x,R,V)).first;
    }
    void Change(int l,int r,int v)
    {
    	Set rr=Split(r+1),ll=Split(l);
    	st.erase(ll,rr);
    	st.insert(Node(l,r,v));
    }
    void Hos(int l1,int r1,int l2,int r2)
    {
    	Set rr=Split(r1+1),ll=Split(l1);
    	int cnt=0;
    	for(Set it=ll;it!=rr;++it)
    		if(it->val)
    			cnt+=it->r-it->l+1;
    	Change(l1,r1,0);
    	rr=Split(r2+1),ll=Split(l2);
    	for(Set it=ll;it!=rr;++it)
    	{
    		if(!cnt)
    			break;
    		if(!it->val)
    		{
    			if(cnt>=it->r-it->l+1)
    				it->val=1,cnt-=it->r-it->l+1;
    			else
    				Change(it->l,it->l+cnt-1,1),cnt=0;
    		}
    	}
    }
    int Search(int l,int r)
    {
    	int ans=0,maxn=0;
    	Set rr=Split(r+1),ll=Split(l);
    	for(Set it=ll;it!=rr;++it)
    		if(it->val)
    			ans=max(ans,maxn),maxn=0;
    		else
    			maxn+=it->r-it->l+1;
    	ans=max(ans,maxn);
    	return ans;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	st.insert(Node(1,n,1));
    	st.insert(Node(n+1));
    	for(int i=1;i<=m;++i)
    	{
    		int opt,l,r,ll,rr;
    		scanf("%d%d%d",&opt,&l,&r);
    		if(!opt)
    			Change(l,r,0);
    		if(opt==1)
    		{
    			scanf("%d%d",&ll,&rr);
    			Hos(l,r,ll,rr);
    		}
    		if(opt==2)
    			printf("%d
    ",Search(l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    [lua]原来这才是表驱动的正确表达方式
    [lua]再版jobSchedule与脚本描述范型
    (景德镇)麻将计分规则
    日志输出法则
    去掉谷歌浏览器获取焦点时默认的input、textarea的边框和背景
    使用@font-face 属性 实现在网页中嵌入任意字体
    【问题】/usr/bin/env: php: 没有那个文件或目录
    Centos下nginx支持https协议
    PHP下生成非重复的id
    PHP下的手机号码效验
  • 原文地址:https://www.cnblogs.com/yexinqwq/p/10208511.html
Copyright © 2020-2023  润新知