2024ICPC网络赛(2)-K.Match——匹配、奇妙的n4 DP

news/2024/9/21 23:12:46

题目:https://qoj.ac/contest/1799/problem/9380
题意:给两个长度为 \(n\) 的序列 \(a,b\),若 \(a_i\oplus b_j\geq k\) 则连一条左侧 \(i\) 到右侧 \(j\) 的边,这样得到一张二分图。对于每个 \(x=1,\dots,n\),询问大小为 \(x\) 的匹配的数量。
\(1\leq n\leq 200\).


首先要知道一般二分图匹配计数大概是做不了的,那么这里必然要思考 \(a_i\oplus b_j\geq k\) 的限制
对位运算考虑类似拆位的东西,比如 \(k=010110\),那么\(\geq k\) 的会形如 1xxxxx,011xxxx,01011x,对于 \(k\) 在二进制下的每个数位,先把 \(A,B\) 对应地按照这一位是 \(0/1\) 划分成 \(A_0,A_1,B_0,B_1\)

  • 如果 \(k\) 这一位是 \(0\)\((A_0,B_1),(A_1,B_0)\) 中间总是两两有边存在。\((A_0,B_0),(A_1,B_1)\) 的边的贡献则可以递归计算,假设其中答案分别是 \(f,g\) 两个序列,则(这里有点符号混用,\(A_0\) 表示这个集合大小): $$ans[i+j+x+y]=f_i\times g_j\times \binom{A_0-i}{x}\binom{B_1-j}{x}\binom{A_1-j}{y}\binom{B_0}{y}\times x!\times y!$$
  • 如果 \(k\) 这一位是 \(1\),则只考虑 \((A_0,B_1),(A_1,B_0)\) 的答案,假设分别是 \(f,g\) 两个序列,则 \(ans_i=\sum_{j} f_j\times g_{i-j}\)

这样暴力转移最坏是 \(A_0\times A_1\times B_0\times B_1\) 的复杂度,注意到 \(A_0+A_1,B_0+B_1\) 是定值,其取到最大值就是当 \(A_0=A_1,B_0=B_1\) 的时候,可以给出复杂度 $$T(n)=2T( \frac{n}{2} )+O(( \frac{n}{2})^4 )=\frac{n^4 }{16}+\frac{n^4 }{128}+\dots$$
但是可以跑的飞快…

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
constexpr int N=205;
constexpr int MOD=998244353;
int n,C[N][N],fact[N];
ll a[N],b[N],k;
vector<int> id;
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
vector<int> solve(int la,int ra,int lb,int rb,int j){if(la>ra||lb>rb)return id;if(j==-1){//边界情况,不受到任何限制,相当于随便选int sa=ra-la+1,sb=rb-lb+1,L=min(sa,sb);vector<int> ans(L+1);for(int i=0;i<=L;i++)ans[i]=(ll)C[sa][i]*C[sb][i]%MOD*fact[i]%MOD;return ans;}int pa=la-1,pb=lb-1;while(pa+1<=ra&&((a[pa+1]>>j)&1)==0)pa++;while(pb+1<=rb&&((b[pb+1]>>j)&1)==0)pb++;int L=min(ra-la+1,rb-lb+1);vector<int> ans(L+1);if(k>>j&1){auto f=solve(la,pa,pb+1,rb,j-1);auto g=solve(pa+1,ra,lb,pb,j-1);for(int i=0;i<f.size();i++)for(int j=0;j<g.size();j++){if(i+j>L)break;add(ans[i+j],(ll)f[i]*g[j]%MOD);}}else{auto f=solve(la,pa,lb,pb,j-1);auto g=solve(pa+1,ra,pb+1,rb,j-1);int A0=pa-la+1,A1=ra-pa,B0=pb-lb+1,B1=rb-pb;f.resize(min(A0,B0)+1);g.resize(min(A1,B1)+1);for(int i=0;i<(int)f.size();i++)for(int j=0;j<(int)g.size();j++)for(int x=0;x<=min(A0-i,B1-j);x++)for(int y=0;y<=min(A1-j,B0-i);y++){if(i+j+x+y>L)break;add(ans[i+j+x+y],(ll)f[i]*g[j]%MOD*C[A0-i][x]%MOD*C[B1-j][x]%MOD*fact[x]%MOD*C[A1-j][y]%MOD*C[B0-i][y]%MOD*fact[y]%MOD);}}return ans;
}
int main(){fastio;fact[0]=1;for(int i=1;i<N;i++)fact[i]=(ll)fact[i-1]*i%MOD;for(int i=0;i<N;i++)C[i][0]=1;for(int i=0;i<N;i++)for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;cin>>n>>k;id={1};rep(i,1,n)cin>>a[i];rep(i,1,n)cin>>b[i];sort(a+1,a+n+1);sort(b+1,b+n+1);auto ans=solve(1,n,1,n,60);for(int i=1;i<=n;i++)cout<<ans[i]<<endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/63138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

领导大规模敏捷Leading SAFe认证培训课

领导大规模敏捷Leading SAFe认证课

asio的buffer

ASIO的buffer理解 asio的buffer结构 任何网络库都有提供buffer的数据结构,这个就是收发数据的缓冲区。 asio提供了mutable_buffer 和 const_buffer这两个结构,他们都是一段连续的空间,首字节存储了后续数据的长度。mutable_buffer用于写服务,const_buffer用于读服务。但是这…

格林公式7

例1 计算积分 \[I=\int_Cx^2ydx-xy^2dy, \]其中C是上半圆 \(\begin{aligned} & \text{ }x^2+y^2=a^2,y\geqslant0,\text{ }\\ & \end{aligned}\) 逆时间方向 \[\begin{aligned} & \text{ }x^2+y^2=a^2,y\geqslant0,\text{ }\\ & \end{aligned} \]考虑到上半…

9.21 abc372f

容易发现平移操作,都是 \(to\) 向左平移。然后更新完了过后,\(x\) 再左移。 当然 dp 数组整体是左移的。 本题一个重点就是,假设整个 dp 不动,让我们的操作反着动。

基于AODV和leach协议的自组网络平台matlab仿真,对比吞吐量,负荷,丢包率,剩余节点个数,节点消耗能量

1.算法仿真效果 matlab2017b仿真结果如下(完整代码运行后无水印):本程序系统是《m基于matlab的AODV,leach自组网网络平台仿真,对比吞吐量,端到端时延,丢包率,剩余节点个数,节点消耗能量》的的升级。升级前原文章链接增加了运动节点的路由测试,包括定向运动,随机运动,静止…

笛卡尔坐标张量简介7

张量(tensor) 这一术语最初是用来描述弹性介质各点应力状态的,后来发展成为力学和物理学的一个有力数学工具,目前力学方面的理论性文献都不同程度地这用了这一工具 由坐标原点和三条不共面的标架直线构成的坐标系称为直线坐标系,如果三标架直线上的单位尺度相同,称为笛卡…

尝试RVC音色克隆团长音色

前言 昨晚玩剑网3突发奇想,把团长声音克隆下来,利用语音喵制作成语音DBM。 这样不管团长开不开团,打团也能有团长声音听了诶嘿嘿。 于是当场关闭游戏声音录了打本的素材,本文就边做边记录。 下载 在B站找到了这个教程: 【你的声音,现在是我的了!】https://www.bilibili.…