P9393 紫丁香 题解

P9393 紫丁香

首先观察一下操作好像是在一个超立方体上连边,而如果直接从询问的点出发寻找最大可达值是不太现实的,考虑从一个终点反向考虑能由哪些点到达。

设 \(g(S)\) 表示要通过操作得到 \(S\) 这个集合至少需要的位集合,假设我们已经得到了这个值的话,就可以按位从高到低贪心考虑当前的询问串能否满足基本需求。

考虑如何计算 \(g(S)\),要得到哪些位必须初始就有,哪些位可以操作得到。设 \(f(S)\) 表示在不减少已有位的情况下,\(S\) 通过操作可以得到的所有 \(1\) 的位。把每个操作的非零位置都表示为掩码,\(f(S)\) 初始为这个操作里为一的位置。然后因为 \(S\) 的已有为不会被减少,所以 \(S\) 的子集的已有位不会被减少,所以对 \(f(S)\) 做 SOSDP,求高维后缀或和即可。

有了 \(f(S)\) 之后,对于每个 \(S\),如果 \(f(S)\) 里含有 \(S\) 中的位,则说明这些位不是必要自带的,而是可以由操作获得的,就把 \(S\) 中的这些位移除,因为最多 \(m\) 位,每次最少移除一位,所以最多操作 \(m\) 次就可以算出最终有必要自带的位。

算出 \(g(S)\) 之后,从高到低贪心考虑即可。

时间复杂度 \(O(m(2^m+n+q))\)。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define _int __int128
#define ull unsigned long long
#define pii pair<int,int>
#define fst first
#define scd second
#define pq priority_queue
#define mkp make_pair
#define popcount(x) __builtin_popcount(x)
#define endl '\n'
int m,n,q;
const int N = 1e5+10,V=(1<<22);
int f[V],g[V];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>m>>n>>q;
    for(int i=1;i<=n;i++){
        string t;
        cin>>t;
        int mk=0,s=0;
        for(int j=0;j<m;j++){
            if(t[j]!='0')mk|=(1<<(m-1-j));
            if(t[j]=='1')s|=(1<<(m-1-j));
        }
        f[mk]|=s;
    }
    for(int i=0;i<m;i++){
        for(int s=0;s<(1<<m);s++){
            if(!((s>>i)&1)){
                f[s]|=f[s^(1<<i)];
            }
        }
    }
    for(int s=0;s<(1<<m);s++){
        int cur=s;
        for(int i=0;i<m;i++){
            int nxt=cur&~f[cur];
            if(cur==nxt)break;
            cur=nxt;
        }
        g[s]=cur;
    }
    while(q--){
        string t;
        cin>>t;
        int s=0;
        for(int i=0;i<m;i++){
            if(t[i]=='1')s|=(1<<(m-1-i));
        }
        int ans=0;
        for(int i=m-1;i>=0;i--){
            int mk=ans|(1<<i);
            if((s&g[mk])==g[mk]){
                ans|=(1<<i);
            }
        }
        for(int i=m-1;i>=0;i--){
            if((ans>>i)&1)cout<<1;
            else cout<<0;
        }
        cout<<endl;
    }
    return 0;
}
posted @ 2026-10-06 22:08  farenara_sayowell  阅读(8)  评论(0)    收藏  举报