• 并不对劲的复健训练-bzoj4592:p4344:[SHOI2015]脑洞治疗仪


    题目大意

    (n)个位置,一开始每个位置上都放着一个东西。每个位置上最多放一个东西。
    (m)个操作,分为以下三类:
    1.给定(l,r),将位置(l)到位置(r)的所有东西都拿走并扔掉。
    2.给定(l_0,r_0,l_1,r_1),将位置(l_0)到位置(r_0)的所有东西都拿出来,用来填位置(l_1)到位置(r_1)的空位,优先填编号小的空位。如果拿出来的东西还有剩的就扔掉。
    3.给定(l,r),询问位置(l)到位置(r)中,最长一段连续空位有多长。
    (n,mleq 2 imes 10^5)

    题解

    对于第三类操作,可以在线段树的每个点记录该区间靠左端最长连续空位、靠右端最长连续空位、最长连续空位、空位总数,这些信息可以(Theta(1))合并。
    在记录这些信息时,“区间赋值”的标记下传的时间可以是(Theta(1))
    第二类操作可以看成给把区间([l_0,r_0])赋值为0,再在([l_1,r_1])中二分一个位置(x),使(x)尽可能大并且([l_0,x])中的空位数不超过([l_0,r_0])拿出的东西,再把([l_0,x])赋值为1.
    看上去([l_1,r_1])被拆成了(logspace n)个区间,要在每个区间内二分,一次二类操作的总时间是(Theta(log^2space n))
    但是(logspace n)个区间中至多有一个是需要二分的,剩下的不是整个区间都被赋值就是整个区间都不被赋值。所以二类操作的时间是(Theta(logspace n))

    代码
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<stack>
    #include<vector>
    #define LL long long
    #define rep(i,x,y) for(int i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(int i=(x);i>=(y);--i)
    #define view(u,k) for(int k=fir[u];~k;k=nxt[k])
    #define maxn 200007
    #define ls (u<<1)
    #define rs (u<<1|1) 
    #define mi ((l+r)>>1)
    using namespace std;
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return x*f;
    }
    void write(int x)
    {
    	char ch[20];int f=0;
    	if(!x){putchar('0'),putchar('
    ');return;}
    	if(x<0)putchar('-'),x=-x;
    	while(x)ch[++f]=x%10+'0',x/=10;
    	while(f)putchar(ch[f--]);
    	putchar('
    ');
    }
    int sum[maxn<<2],lx[maxn<<2],rx[maxn<<2],mx[maxn<<2],mk[maxn<<2],ad,pref;
    int n,m;
    void pu(int u,int l,int r)
    {
    	sum[u]=sum[ls]+sum[rs];
    	if(sum[ls]==mi-l+1)lx[u]=(mi-l+1)+lx[rs];
    	else lx[u]=lx[ls];
    	if(sum[rs]==r-mi)rx[u]=(r-mi)+rx[ls];
    	else rx[u]=rx[rs];
    	mx[u]=max(max(mx[ls],mx[rs]),lx[rs]+rx[ls]);
    	return;
    }
    void mark(int u,int l,int r,int k)//k=0,1
    {
    	mk[u]=k;
    	if(k==0){sum[u]=mx[u]=lx[u]=rx[u]=r-l+1;}
    	else {sum[u]=mx[u]=lx[u]=rx[u]=0;}
    	return;
    }
    void pd(int u,int l,int r){if(mk[u]!=-1)mark(ls,l,mi,mk[u]),mark(rs,mi+1,r,mk[u]),mk[u]=-1;}
    int ask(int u,int l,int r,int x,int y)
    {
    	if(x<=l&&r<=y){int tmp=sum[u];mark(u,l,r,0);return r-l+1-tmp;}
    	pd(u,l,r);int res=0;
    	if(x<=mi)res+=ask(ls,l,mi,x,y);
    	if(y>mi)res+=ask(rs,mi+1,r,x,y);pu(u,l,r);
    	return res;
    }
    int query(int u,int l,int r,int x,int y)
    {
    	if(x<=l&&r<=y)
    	{	
    		int res=pref+lx[u];
    		pref=(sum[u]==r-l+1)?(pref+sum[u]):rx[u];
    		return max(res,mx[u]);
    	}
    	pd(u,l,r);int res=0;
    	if(x<=mi)res=query(ls,l,mi,x,y);
    	if(y>mi)res=max(res,query(rs,mi+1,r,x,y));
    	return res;
    }
    void work(int u,int l,int r)
    {
    	if(!ad)return;
    	if(l==r&&ad>sum[u]){ad-=sum[u],mark(u,l,r,1);return;}
    	if(l==r)return; 
    	pd(u,l,r); 
    	if(ad>=sum[ls])ad-=sum[ls],mark(ls,l,mi,1),work(rs,mi+1,r);
    	else work(ls,l,mi);
    	pu(u,l,r);return;
    }
    void chg(int u,int l,int r,int x,int y)
    {
    	if(x<=l&&r<=y)
    	{
    		if(ad)
    		{
    			if(ad>=sum[u])ad-=sum[u],mark(u,l,r,1);
    			else work(u,l,r);
    		}
    		return;
    	}
    	pd(u,l,r);
    	if(x<=mi)chg(ls,l,mi,x,y);
    	if(y>mi)chg(rs,mi+1,r,x,y);
    	pu(u,l,r);return;
    }
    int main()
    {
    	n=read(),m=read();
    	memset(mk,-1,sizeof(mk));
    	while(m--)
    	{
    		int f=read();
    		if(f==0){int l=read(),r=read(),t=ask(1,1,n,l,r);}
    		else if(f==1)
    		{
    			int l0=read(),r0=read(),l1=read(),r1=read();ad=ask(1,1,n,l0,r0);
    			chg(1,1,n,l1,r1);			
    		}
    		else 
    		{
    			int l=read(),r=read();pref=0;
    			write(query(1,1,n,l,r));
    		}
    	}
    	return (~(0-0)+1);
    }
    
    一些感想

    教练追求的“最佳训练方式”只是“让一群人中出现尽可能多的拿奖的人的训练方式”,而每个人追求的“最佳训练方式”是“让自己这一个人更厉害的训练方式”。
    所以要么不迷信权威(包括但不限于教练、周围看似很厉害的人、路人),要么指听最权威的“权威”的那句“不迷信权威”。

  • 相关阅读:
    div 和 span的区别
    div 和 span的区别
    javascript类的定义及成员修改
    C# bho操作dom 同时带有隐藏工具栏功能,菜单栏
    javascript类的定义及成员修改
    数据库原理8个例子sql语句
    数据库原理8个例子sql语句
    C++的声明和定义的出别
    C++的声明和定义的出别
    Visual Studio 添加图标和版本
  • 原文地址:https://www.cnblogs.com/xzyf/p/12664447.html
Copyright © 2020-2023  润新知