21.10.14 test
题目 WOJ5078 到 WOJ5081
T1 Problem A \(\color{green}{100}\)
由于每轮要选择尽量多的边删除,所以想到无向图的生成树,因为在生成树上再加一条边就会形成环。然后要求边权和最大的最大的。那么题意就是求 \(k\) 颗最大生成树。
先把边按边权从大到小排,考虑朴素 Kruscal ,维护 \(k\) 次并查集,复杂度 \(O(km)\) 过不去。考虑同时维护 \(k\) 个并查集,那么枚举每条边,将其加入到第一个 \(u,v\) 不连通的并查集中。由于每次都要求加入到最前面的并查集,那么任意 \(u,v\) 的连通性一定是单调的,也就是前面不连通,后面联通,所以每次二分找这个并查集。
下面是我赛时的做法。
我赛时写的神秘优化也跑的飞快,估计是出题人没有想到这种优化,没有刻意卡。是对每次 \(O(k)\) 找加入的并查集的优化。有点像 Dinic 的当前弧优化,就是从上一次对 \(u,v\) 边找到的并查集的下一个开始找,显然重边越多跑的越快。
code:
#include<bits/stdc++.h>
using namespace std;
#define in read()
inline int read(){
int p=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){p=p*10+c-'0';c=getchar();}
return p*f;
}
const int N=1e3+5;
const int M=3e5+5;
const int K=1e4+5;
struct edge{
int u,v,w,o;
}e[M];
int n,m,k;
inline bool cmp(edge a,edge b){
return a.w>b.w;
}
int vis[M];
int fa[N][K];
inline int getf(int x,int tk){
if(fa[x][tk]==x)return x;
return fa[x][tk]=getf(fa[x][tk],tk);
}
int cur[N][N];
signed main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
register int i;
n=in,m=in,k=in;
for(i=1;i<=m;++i)
e[i].u=in,e[i].v=in,
e[i].w=in,e[i].o=i;
sort(e+1,e+1+m,cmp);
for(i=1;i<=n;++i)
for(int j=1;j<=k;j++)
fa[i][j]=i;
for(i=1;i<=m;++i){
int u=e[i].u,v=e[i].v;
int t=cur[u][v]+1,f1=getf(u,t),f2=getf(v,t);
while(f1==f2&&t<k)
t++,f1=getf(u,t),f2=getf(v,t);
if(f1==f2)continue;
vis[e[i].o]=t;
fa[f2][t]=f1;
cur[u][v]=cur[v][u]=t;
}
for(i=1;i<=m;++i)
cout<<vis[i]<<'\n';
return 0;
}
T2 Problem B \(\color{red}{98}\)
由于操作只能用行来更新列,所以正确的构造方案一定是先构造出一整行黑色,然后再逐列修改。
先考虑无解,当且仅当图中没有黑色时无解。因为只要有一个黑色,将黑色对应行修改每列一定能构造出一整行黑。
判断无解之后图中一定有黑色。
考虑将每行作为要构造的整行黑之后取最小值。
如果第 \(i\) 列有黑,那么那么用这个黑一定可以构造出全黑的第 \(i\) 行;如果第 \(i\) 列没有黑,那么随便找一个有黑的行操作一次就可以让第 \(i\) 列有黑。
然后考虑第 \(i\) 行的操作数,按上述操作让第 \(i\) 列有黑。然后遍历一行,有一个白就算一次操作。将整行染黑之后再遍历每列,如果这一列全是黑就不操作,否则算一次操作。
#include<bits/stdc++.h>
using namespace std;
const int N=505;
int n;
int mp[N][N];
int line[N];
bool OK[N];
bool cisb[N];
int tans=0x7fffffff;
bool NO=true;
signed main(){
// freopen("b.in","r",stdin);
// freopen("b.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
char c;cin>>c;
mp[i][j]=(c=='#');
if(mp[i][j])OK[j]=1;
if(mp[i][j])NO=false;
}
if(NO){cout<<-1;return 0;}
for(int i=1;i<=n;i++){
cisb[i]=1;
for(int j=1;j<=n;j++)
if(!mp[j][i])cisb[i]=0;
}
for(int i=1;i<=n;i++){
int ans=n;
if(!OK[i])ans++;
for(int j=1;j<=n;j++){
if(cisb[j])ans--;
if(!mp[i][j])ans++;
}
tans=min(ans,tans);
}
cout<<tans;
return 0;
}
T3 Problem C \(\color{red}{60}\)
想了一堆关于 \(\sqrt n\) 的无用性质,终究没有注意到正解的性质。
乘积大于 \(n^m\) 的方案数等于乘积小于 \(n^m\) 的方案数。
考虑一个序列 \(p_1,p_2,\cdots,p_{2m}\),且\(p_1p_2\cdots p_{2m}=t<n^m\)
那么有 \(\frac{n}{p_1},\frac{n}{p_2},\cdots,\frac{n}{p_{2m}}\),且\(\frac{n}{p_1}\frac{n}{p_2}\cdots\frac{n}{p_{2m}}=\frac{n^{2m}}{t}>n^m\)
所以每一个乘积小于 \(n^m\) 的序列对应一个乘积大于 \(n^m\) 的序列,所以我们只需要算出乘积等于 \(n^m\) 的序列数就好了。
对于乘积等于 \(n^m\) 的数量,可以用 dp 做。题解曰,经典背包
考虑求出 \(n^m\) 的质因子也就是 \(n\) 的质因子且个数乘以 \(m\)。那么问题就是这些质因子分配到 \(2m\) 个位置的方案数。
考虑将每个质因子单独做最后乘起来就是答案。
记 \(n\) 的一个质因子为 \(p\),有 \(c\) 个。
设 \(f[i][j]\) 表示前 \(i\) 个位置一共分配了 \(j\) 个 \(p\)。显然 \(f\) 的范围是 \(2m*c*m\),\(c\) 的期望个数是 \(\log n\) ,所以状态数是 \(m^2\log n\)。
由于要求每个位置整除 \(n\),所以每个位置最多分配 \(c\) 个\(p\) ,于是转移时枚举当前位置分配了几个 \(p\),方程为:
\]
可以滚动数组滚掉第一维。
时间复杂度分析:\(p\) 的种类约为 \(\log n\),个数约为 \(\log n\),外层循环每个 \(p\),内层 dp 状态数 \(m^2\log n\),转移 \(p\) 的个数,所以总复杂度大概是 \(O(m^2(\log n)^3)\)。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define in read()
inline int read(){
int p=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){p=p*10+c-'0';c=getchar();}
return p*f;
}
const int mod=998244353;
int inv2=499122177;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int n,m;
int p[100],pn;
int cnt[100];
void getp(int x){
int ans=x;
for(int i=2;i*i<=x;i++){
if(x%i==0)p[++pn]=i;
while(x%i==0)cnt[pn]++,x/=i;
}
if(x!=1)p[++pn]=x,cnt[pn]=1;
}
int f[205][6005];
int ans=1,res=1;
signed main(){
cin>>n>>m;
getp(n);
for(int i=1;i<=pn;i++)
res=res*(cnt[i]+1)%mod;
for(int l=1;l<=pn;l++){
memset(f,0,sizeof(f));
for(int i=0;i<=cnt[l];i++)
f[1][i]=1;
for(int i=2;i<=m<<1;i++){
for(int j=0;j<=cnt[l]*m;j++){
for(int k=0;k<=cnt[l];k++){
f[i][j]=(f[i][j]+f[i-1][j-k])%mod;
}
}
}
ans=ans*f[m<<1][cnt[l]*m]%mod;
}
ans=(qpow(res,(m<<1))+ans+mod)%mod*inv2%mod;
cout<<ans;
return 0;
}
有个想法是用经典 dp 求出把 \(n\) 个数分配到 \(m\) 个方案数,然后容斥掉不合法的分配,但是写挂了。
T4 Problem D \(\color{purple}{0}\)
freoepn,虽然改过来也是挂的
明天改。
21.10.14 test的更多相关文章
- Capture One 21 Pro 14.0.2.36中文版安装教程
Capture One 21 Pro 14.0.2.36 for windows是一款由丹麦PHASE ONE飞思公司推出的.非常专业强大的图像处理编辑工具. 下载 Capture One 21 Pr ...
- Noip模拟76 2021.10.14
T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...
- 背水一战 Windows 10 (14) - 动画: 线性动画, 关键帧动画
[源码下载] 背水一战 Windows 10 (14) - 动画: 线性动画, 关键帧动画 作者:webabcd 介绍背水一战 Windows 10 之 动画 线性动画 - ColorAnimatio ...
- 2016年12月15日 星期四 --出埃及记 Exodus 21:10
2016年12月15日 星期四 --出埃及记 Exodus 21:10 If he marries another woman, he must not deprive the first one o ...
- Thinkpad W520 + Ubuntu 12.04LTS, 13.10, 14.04LTS安装Nvidia显卡驱动设置
Thinkpad W520 + Ubuntu 12.04LTS, 13.10, 14.04LTS安装Nvidia显卡驱动设置 http://henzhai.com/tech/2012/07/w520- ...
- macOS 10.14虚拟机安装教程
windows10下安装vmware14.0以及macOS 10.14图文详解 工具/原料 windows10 vmware 14.0 macOS 10.14懒人版 mac补丁unlocker工具 ...
- OS + macOS Mojave 10.14.4 / sushi / ssh-keygen / ssh-copy-id
s 系统版本: macOS 10.14.4 (18E226) 内核版本: Darwin 18.5.0 型号名称: Mac mini 2014 型号标识符: Macmini7,1 处理器名称: Inte ...
- VMware15安装MAC(MAC OS 10.13)(OS X 10.14)原版可升级最新可解锁macOS Unlocker3.0(OS X 10.13)
目录树 1.1.2安装环境: 1.1.3所需资源: 1.1.4 Unlocker 3.0解锁 1.1.5 配置环境 1.1.6开始安装 1.1.7开启虚拟机进入MAC安装界面 1.1.8 macO ...
- APPLE-SA-2019-3-25-2 macOS Mojave 10.14.4,Security Update 2019-002 High Sierra, Security Update 2019-002 Sierra
APPLE-SA-2019-3-25-2 macOS Mojave 10.14.4, Security Update2019-002 High Sierra, Security Update 2019 ...
随机推荐
- 迷你DVD
public class DVD { private int ID;//id private String status;//状态 private String name;//名称 private S ...
- eclipes常见操作总结及项目2和3经验总结
eclipes常见操作总结及项目2经验总结 eclipes提示: 打开eclipes 选择window->perference->java->editor->content a ...
- tp5 引入 没有命名空间的类库的方法(以微信支付SDK为例)
use think\Loader; Loader::import('Wxpay.WxPay',EXTEND_PATH,'.Api.php'); 注意扩展名的点"."不能省略 使用之 ...
- 超详细的VMware安装Centos7教程
下载centos镜像 https://wiki.centos.org/Download 注:真正生产环境的oracle数据库一般是一整台服务器只用作数据库,不会安装其他应用,也不会安装xwindow图 ...
- P3335-[ZJOI2013]蚂蚁寻路【dp】
正题 题目链接:https://www.luogu.com.cn/problem/P3335 题目大意 给出\(n\times m\)的网格,每个格子有权值.一个回路在格子的边上,要求有\(2\tim ...
- P3793-由乃救爷爷【分块,ST表】
正题 题目链接:https://www.luogu.com.cn/problem/P3793 题目大意 给出\(n\)个数字的一个序列\(m\)次询问区间最大值 保证数据随机 \(1\leq n,m\ ...
- 51nod1600-Simple KMP【SAM,树链剖分】
正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1600 题目大意 给出一个字符串\(s\),每次在最后插入一个字符后求它的 ...
- 如何从阿里云Code升级至云效Codeup
如果你还在使用阿里云Code,不防看看如何从阿里云Code升级至云效Codeup,云效代码管理Codeup是阿里云出品的一款企业级代码管理平台,提供代码托管.代码评审.代码扫描.质量检测等功能,全方位 ...
- Kettle学习笔记(二)— 基本操作
目录 Kettle学习笔记(一)- 环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 打开Kettle 打开 ...
- 如何使用云效Flow做质量检测,保障高质量的交付速度
使用云效Flow做质量检测,保障高质量的交付速度,云效「Flow」 提供代码扫描. 安全扫描和各种自动化测试能力,支持人工测试卡点.自动化验证卡点等多种质量红线,确保业务质量.云效流水线 Flow 流 ...