1 条题解

  • 0
    @ 2025-8-24 23:06:04

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 缪凌锴_Mathew
    希↑望→计↓划↑可→以↑成↓功↓ | 离错真机

    搬运于2025-08-24 23:06:04,当前版本为作者最后更新于2024-11-17 13:33:15,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    场上胡了一堆结论过了,证明一下这些结论。

    下面我们只考虑 n>5n>5 的情况,n5n\le 5 corner case 太多了直接跑暴力。

    接下来认为删除后球会自动往前补位(即只考虑红球,蓝球不重要)。

    这样一次操作必定为操作 i1,i,i+1i-1,i,i+1 这三个位置。

    发现删除 i,i+1i,i+1 和删除三个位置中任意两个没有区别,于是操作是对称的。

    结论 115in45\le i\le n-4ii 为奇数,最后一定能剩下权值 pip_i

    考虑 pi1>pip_{i-1}>p_i 的情况,pi1<pip_{i-1}<p_i 是对称的。

    • j<i1,pj>pi\exists j<i-1,p_j>p_i,那么不断操作 1,2,31,2,3 这三个位置,选择 p1max(p1,p2,p3)p'_1\gets\max(p_1,p_2,p_3)

      操作直到球 ii 到达 33 的位置,也就是把 1i21\sim i-2 的球合成一个最大值。

      因为 j<i1,pj>pi\exists j<i-1,p_j>p_i,合出来的 p1>p3=pip'_1>p'_3=p_i,又 p2=pi1>p3=pip'_2=p_{i-1}>p'_3=p_i,此时操作 1,2,31,2,3 这三个球,选择 p1min(p1,p2,p3)p'_1\gets\min(p_1,p_2,p_3),这样 p1=pip'_1=p_i

    • j<i1,pj<pi\forall j<i-1,p_j<p_i,操作 i3,i2,i1i-3,i-2,i-1,选择 pi3min(pi3,pi2,pi1)p'_{i-3}\gets \min(p_{i-3},p_{i-2},p_{i-1})

      这样去掉了 pi1p_{i-1}pip_i 是前缀最大,直接不断选择 max\max 操作即可把 ii 移动至 11

      即不断操作 1,2,31,2,3,选择 p1max(p1,p2,p3)p'_1\gets\max(p_1,p_2,p_3)

    以上证明了可以删掉 1i11\sim i-1,对称,同理可以删掉 i+1ni+1\sim n

    结论 221in1\le i\le nii 为偶数,最后不能剩下权值 pip_i 当且仅当 pip_i 两侧权值范围无交。

    权值范围无交意思是 maxj<ipj<pi<minj>ipj\max\limits_{j<i}p_j<p_i<\min\limits_{j>i}p_j 或者 minj<ipj>pi>maxj>ipj\min\limits_{j<i}p_j>p_i>\max\limits_{j>i}p_j

    考虑 pi+1>pip_{i+1}>p_i 的情况,pi+1<pip_{i+1}<p_i 是对称的。

    j<i1,pj>pi\exists j<i-1,p_j>p_i,那么不断操作 1,2,31,2,3 这三个位置,选择 p1max(p1,p2,p3)p'_1\gets\max(p_1,p_2,p_3)

    操作直到球 ii 到达 22 的位置,也就是把 1i21\sim i-2 的球合成一个最大值。

    因为 j<i1,pj>pi\exists j<i-1,p_j>p_i,合出来的 p1>p2=pip'_1>p'_2=p_i,又 p3=pi+1>p2=pip'_3=p_{i+1}>p'_2=p_i,此时操作 1,2,31,2,3 这三个球,选择 p1min(p1,p2,p3)p'_1\gets\min(p_1,p_2,p_3),这样 p1=pip'_1=p_i

    又根据结论 11,可以删掉 i+2ni+2\sim n,这样最终剩下 pip_i

    对称地,还有可能 pi1>pip_{i-1}>p_ij>i+1,pj>pi\exists j>i+1,p_j>p_i

    剩下的情况就是 maxj<ipj<pi<minj>ipj\max\limits_{j<i}p_j<p_i<\min\limits_{j>i}p_j 或者 minj<ipj>pi>maxj>ipj\min\limits_{j<i}p_j>p_i>\max\limits_{j>i}p_j

    这些情况无论怎么操作,必定会操作 i1,i,i+1i-1,i,i+1,这时 pip_i 是中位数,不能保留。

    接下来就只用考虑 p3p_3pn2p_{n-2} 能不能保留,两种情况对称,只考虑 p3p_3 行不行。

    • p3p_3 不是 p1,p2,p3p_1,p_2,p_3 的中位数,删去 p1,p2p_1,p_2,根据结论 11,可以删掉 4n4\sim n,剩下 p3p_3

    • p3p_3p1,p2,p3p_1,p_2,p_3 的中位数,不妨设 p1>p3>p2p_1>p_3>p_2。(p1<p3<p2p_1<p_3<p_2 是对称的)

      操作 1,2,31,2,3 或者 3,4,53,4,5 肯定无用,只有可能操作 2,3,42,3,4

      只有 p2<p3,p4<p3p_2<p_3,p_4<p_3 才能操作 2,3,42,3,4,于是需要一个 <p3<p_3p4p_4

      找到第一个 i>3,pi<p4i>3,p_i<p_4ii,找不到无解。

      • ii 是奇数,第一个 j>i,pj>p3j>i,p_j>p_3ii,找不到无解。

        取 min 合成 p4pip_4\sim p_ip4<p3p'_4<p_3

        取 max 合成 pi+1pnp_{i+1}\sim p_np5>p3p'_5>p_3

        p2>p3<p4p_2>p_3<p'_4,取 min 删去 p2p_2p4p'_4

        p1>p3<p5p_1>p_3<p'_5,取 min 删去 p1p_1p5p'_5

        剩下 p3p_3,必定有解。

      • ii 是偶数,第一个 j+1>i,pj>p3j+1>i,p_j>p_3ii,找不到无解。

        取 min 合成 p4pi+1p_4\sim p_{i+1}p4<p3p'_4<p_3

        取 max 合成 pi+2pnp_{i+2}\sim p_np5>p3p'_5>p_3

        同理,必定有解。

    代码实现模拟上述过程即可,时间复杂度 O(n)O(n)

    #include<map>
    #include<set>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<string>
    #include<bitset>
    #include<numeric>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN=1e6+10;
    const int N=1e6;
    const int INF=0x3f3f3f3f;
    const long long LINF=0x3f3f3f3f3f3f3f3f;
    const int mod=998244353;
    int n;
    int a[MAXN];
    bool ans[MAXN];
    int suf_max[MAXN],suf_min[MAXN];
    bool f[32];
    void dfs(int s){
    	if(f[s]){
    		return ;
    	}
    	f[s]=true;
    	if(s==(s&-s)){
    		return;
    	}
    	for(int i=1;i<n-1;i++)
    	{
    		if(~s&(1<<i)){
    			continue;
    		}
    		int j=i-1,k=i+1;
    		while(~j&&~s&(1<<j))
    		{
    			j--;
    		}
    		while(k^n&&~s&(1<<k))
    		{
    			k++;
    		}
    		if(~j&&k^n){
    			int p=a[i+1]+a[j+1]+a[k+1]-max({a[i+1],a[j+1],a[k+1]})-min({a[i+1],a[j+1],a[k+1]});
    			if(a[i+1]==p){
    				dfs(s^(1<<i)^(1<<j));
    				dfs(s^(1<<i)^(1<<k));
    			}
    			if(a[j+1]==p){
    				dfs(s^(1<<j)^(1<<i));
    				dfs(s^(1<<j)^(1<<k));
    			}
    			if(a[k+1]==p){
    				dfs(s^(1<<k)^(1<<i));
    				dfs(s^(1<<k)^(1<<j));
    			}
    		}
    	}
    }
    inline void work(){
    	if(a[1]<a[3]&&a[2]>a[3]){
    		ans[a[3]]=false;
    		for(int i=4;i<=n;i++)
    		{
    			if(a[i]>a[3]){
    				for(int j=i+1+(i&1);j<=n;j++)
    				{
    					if(a[j]<a[3]){
    						ans[a[3]]=true;
    						break;
    					}
    				}
    				break;
    			}
    		}
    	}
    	if(a[1]>a[3]&&a[2]<a[3]){
    		ans[a[3]]=false;
    		for(int i=4;i<=n;i++)
    		{
    			if(a[i]<a[3]){
    				for(int j=i+1+(i&1);j<=n;j++)
    				{
    					if(a[j]>a[3]){
    						ans[a[3]]=true;
    						break;
    					}
    				}
    				break;
    			}
    		}
    	}
    }
    inline void solve(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    	}
    	if(n<=5){
    		memset(f,false,sizeof(f));
    		dfs((1<<n)-1);
    		for(int i=1;i<=n;i++)
    		{
    			ans[a[i]]=f[1<<(i-1)];
    		}
    		for(int i=1;i<=n;i++)
    		{
    			putchar(ans[i]+'0');
    		}
    		putchar('\n');
    		return ;
    	}
    	memset(ans,true,sizeof(bool)*(n+1));
    	suf_max[n]=a[n];
    	suf_min[n]=a[n];
    	for(int i=n-1;i;i--)
    	{
    		suf_max[i]=max(suf_max[i+1],a[i]);
    		suf_min[i]=min(suf_min[i+1],a[i]);
    	}
    	int pre_max=a[1],pre_min=a[1];
    	for(int i=1;i<=n;i++)
    	{
    		if(~i&1&&(pre_max<a[i]&&a[i]<suf_min[i+1]||pre_min>a[i]&&a[i]>suf_max[i+1])){
    			ans[a[i]]=false;
    		}
    		pre_max=max(pre_max,a[i]);
    		pre_min=min(pre_min,a[i]);
    	}
    	work();
    	reverse(a+1,a+1+n);
    	work();
    	for(int i=1;i<=n;i++)
    	{
    		putchar(ans[i]+'0');
    	}
    	putchar('\n');
    }
    signed main(){
    	#ifdef LOCAL
    	freopen("data.in","r",stdin);
    	freopen("data.out","w",stdout);
    	atexit([](){fprintf(stderr,"%.3lfs\n",(double)clock()/CLOCKS_PER_SEC);});
    	#endif
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		solve();
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    10766
    时间
    1000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者