首页 > 其他分享 >CF1326F2 Wise Men (Hard Version) 题解

CF1326F2 Wise Men (Hard Version) 题解

时间:2024-08-24 12:25:47浏览次数:10  
标签:ch Wise int 题解 Men long FF dvd define

题目链接

点击打开链接

题目解法

挺难的。可能一步一步推下来也没那么复杂(?
基本 copy tzc_wk 的题解/bx

肯定不能像 \(F1\) 用普通的状压求,一个技巧是容斥
考虑令 \(f_S\) 表示 \(S\) 中为 \(1\) 的位置 \(p_i\) 和 \(p_{i+1}\) 必须认识,为 \(0\) 的位置随便
\(f\) 数组相当于答案的高维后缀和,若求出 \(f\),还原答案是简单的

考虑如何求出 \(f\)
我们把 \(S\) 的二进制表示拆分成若干个连续 \(1\) 段,假设长度为 \(l_1,l_2,...,l_m\)
这相当于把全集分成 \(m\) 个集合,满足 \(|S_i|=l_i\),然后把 \(S_i\) 内部钦定一个顺序,满足相邻两个都认识 的方案数
后面的部分是好做的,令 \(dp_{S,i}\) 表示当前有集合 \(S\) 中的人,最后一个人是 \(i\),且相邻人都认识的方案数,转移是 simple 的
前面的部分比较有启发性
令 \(g_S\) 表示 \(S\) 集合内任意排序,相邻人都认识的方案数
那么总方案数就是 \(\prod \limits_{|S_i|=l_i,S_1|S_2|...|S_m=全集} g_{S_i}\)
这东西看上去类似子集卷积
我们在记一维 \(popcount\),然后对每个 \(popcount\) 做一遍 \(fwt\)
然后再把 \(l_i\) 对应的点值序列都对应位相乘,最后 \(ifwt\) 还原回去即可
注意到我们只需要全集的值,所以这一部分并不需要显式的 \(ifwt\),直接容斥即可

但这样做复杂度是 \(O(4^nn)\),显然不太行
但我们发现 \(l_i\) 的顺序是不影响答案的,所以我们只求 \(l_i\) 不降的方案数即可
不难发现这相当于枚举 \(n\) 的拆分数,而 \(18\) 的拆分数个数只有 \(385\)

所以最后的时间复杂度为 \(O(385\times 2^n+2^nn^2)\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
typedef vector<int> vi;
const int N=18;
int n,ppc[1<<N];
LL ans[1<<N],rec[N+1][1<<N],f[1<<N][N];
bool E[N][N];
int all(int x){ return (1<<x)-1;}
void fwtor(LL *val){ F(i,0,n-1) F(S,0,(1<<n)-1) if(S>>i&1) val[S]+=val[S^(1<<i)];}
map<vi,LL> mp;
vi dvd;
LL mul[N+1][1<<N];
void doit(){
    LL res=0;
    F(S,0,all(n)){
        if((n-ppc[S])&1) res-=mul[dvd.size()][S];
        else res+=mul[dvd.size()][S];
    }
    mp[dvd]=res;
}
void dfs(int lef,int dep){
    if(!lef){ doit();return;}
    F(i,dep,lef){
        dvd.pb(i);
        F(S,0,(1<<n)-1) mul[dvd.size()][S]=mul[SZ(dvd)][S]*rec[i][S];
        dfs(lef-i,i);
        dvd.pop_back();
    }
}
int main(){
    ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
    cin>>n;
    F(i,0,n-1){
        string str;cin>>str;
        F(j,0,n-1) E[i][j]=str[j]-48;
    }
    F(S,0,all(n)) ppc[S]=__builtin_popcount(S);
    F(i,0,n-1) f[1<<i][i]=1;
    F(S,1,all(n)) F(i,0,n-1) if(f[S][i]){
        rec[ppc[S]][S]+=f[S][i];
        F(j,0,n-1) if(!(S>>j&1)&&E[i][j]) f[S^1<<j][j]+=f[S][i];
    }
    F(i,1,n) fwtor(rec[i]);
    F(i,0,all(n)) mul[0][i]=1;
    dfs(n,1);
    F(S,0,all(n-1)){
        dvd.clear();
        F(i,0,n-1){
            int j=i;
            while(j<n-1&&(S>>j&1)) j++;
            dvd.pb(j-i+1),i=j;
        }
        sort(dvd.begin(),dvd.end());
        ans[S]=mp[dvd];
    }
    F(i,0,n-2) F(S,0,all(n-1)) if(S>>i&1) ans[S^(1<<i)]-=ans[S];
    F(i,0,all(n-1)) printf("%lld ",ans[i]);puts("");
    return 0;
}

标签:ch,Wise,int,题解,Men,long,FF,dvd,define
From: https://www.cnblogs.com/Farmer-djx/p/18377638

相关文章

  • 【kubernetes】The LocalStreamEnvironment cannot be used when submitting
    1.概述新手上路,首先参考文章:【Flink】Mac下使用flink-kubernetes-operator本地运行flink程序在这个文章中,我们知道了如何使用demo提交flink任务。但是如果我们的机器没有kubectl命令,我们改怎么提交任务到flink呢?这里我们可以使用代码提交,此处文章参考:【kubernetes】使......
  • 开源的个人独立博客Moments社交优化项目源码
    开源的个人独立博客Moments社交优化项目源码,为你提供了一个与关注的博客作者和读者互动的全新方式,让你的博客体验更加丰富和充实。Moments的核心目标是通过整合各种订阅源,如RSS和Atom,将你感兴趣的博客转化为一个个人朋友圈。你可以订阅来自世界各地的博客,并实时获取他们的最新......
  • P6348 [PA2011] Journeys 题解
    Description一个星球上有\(n\)个国家和许多双向道路,国家用\(1\simn\)编号。但是道路实在太多了,不能用通常的方法表示。于是我们以如下方式表示道路:\((a,b),(c,d)\)表示,对于任意两个国家\(x,y\),如果\(a\lex\leb,c\ley\led\),那么在\(x,y\)之间有一条道路。首都位于......
  • 2018年安徽省赛小学组题解
    T1:移动石子(stone)题目描述期待已久的“清明”假期终于到了。清明节是中华民族几千年来留下的优良传统,它有利于弘扬孝道亲情,唤醒家庭共同记忆,促进家庭成员乃至民族的凝聚力和认同感。小学生卡卡西非常高兴,因为清明前后正是踏青的好时光,他终于可以和小伙伴们一起出去踏青了!然而,天......
  • CF1514D Cut and Stick 题解
    题目传送门前置知识可持久化线段树解法若区间内不存在绝对众数,直接保持这一段即可。若存在绝对众数,贪心地想肯定要尽可能地把其分开还要限制出其他数使其不成为绝对众数。容易发现设绝对众数出现次数为\(cnt\),取\(cnt-1\)个其他数和绝对众数配对最优。但可能其他数不够\(......
  • 题解:P10906 [蓝桥杯 2024 国 B] 合法密码
    本来以为字符串多大,结果就这点,直接暴力。枚举起始点,对于每个起始点枚举后面\(8\sim16\)位有没有能用的即可。最后答案为\(400\)。附:计算代码枚举代码如下:for(inti=0;i<n;++i){for(intlength=8;length<=16;++length){if(i......
  • 读论文《Behavior Pattern Mining-based Multi-Behavior Recommendation》
    论文地址:arxiv.org/pdf/2408.12152v1项目地址:GitHub-rookitkitlee/BPMR基于行为模式挖掘的多行为推荐:论文提出了一种新颖的多行为推荐算法(BPMR),旨在通过分析用户和项目之间的复杂交互模式来提高推荐系统的有效性。这种方法特别关注于用户除了购买之外的其他行为,例如页面浏览......
  • el-upload重复上传文件失效(Element-Plus)
    当指定了参数limit=1,再次上传就会无效以下是官方文档给出的解决方法示例通过on-exceed来定义超出限制时的行为<template><el-uploadref="uploadRef":limit="1":on-exceed="handleExceed":auto-upload="false"></el-upload>......
  • 题解:P10903 [蓝桥杯 2024 省 C] 商品库存管理
    题目大意有一个初始化为\(0\)的长度为\(n\)的序列,现有\(m\)个操作,每次将区间\([L,R]\)中的数量加\(1\),求如果不做某个操作将会有多少个数量为\(0\)的量。解题思路当看见这句话时就想到了差分,这题我们可以使用差分先处理将所有的操作执行后的数组,然后在算出如果减......
  • P10404 「XSOI-R1」原神数 题解
    一篇题解需要一张头图。容易发现超过十位的数都不是原神数,因为只有十个数字,不可能保证十一个位置互不相同。同时恰好十位的数也不可能是原神数,因为数位互不相同的十位数的数位和为\(45\),被\(3\)整除,一定是\(3\)的倍数。于是把原神数的范围缩小到\([1,10^9)\)。显然不......