Atcoder 好题

Atcoder 好题

ARC193C Grid Coloring 3

题面:

给你一个 \(n\times m\) 的网格初始全没有被染色,每次可以选择 \((x,y,c),1\leq x\leq n,1\leq y\leq m,1\leq c\leq C\) 将,第 \(x\) 行和第 \(y\) 列全部染成第 \(c\) 种颜色(覆盖之前的颜色),可以操作任意次,问最终有多少种不同的染色方案。\(n,m<=400,C<=1e9\)

题解:

因为后面染色能覆盖前面的颜色,所以要将操作序列时光倒流,现在变成每次染还没有颜色的格子,有多少种方案。

在第一次操作(翻转操作序列前的最后一次操作)染了一个十字之后,钦定后面的每一次操作中心 \((x,y)\) 必须已经被染过色,那第 \(x\) 行和第 \(y\) 列中必有一个已经全部染色了,那么操作就变成了每次给一行或者一列染一个颜色(分别记为 \(A,B\) 操作),显然最终的答案是不变的。

但这时直接枚举每次操作是啥仍然不太可做,原因是对于操作序列中两次连续的 \(A\) 操作或 \(B\) 操作,交换他们的操作顺序不影响答案,所以会算重。由于 \(A\)\(A\) 之间互不干扰,\(B\)\(B\) 之间也是,这启发我们每次可以同时操作操作序列中一段极长的 \(A\)\(B\),显然这样转化后答案仍然是对的,这就好做了。

将第一段特殊处理,枚举最终有 \(i\)\(j\) 列都是第一次操作的颜色,方案数是 \(C\binom{n}{i}\binom{m}{j}\),然后进行 \(dp\)
先设一个大概的雏形 \(f_{n,m,* }\) 表示给 \(n\times m\) 的网格染色的答案。
在此之后的下一个极长段中,显然不能有一行或一列的颜色和第一次操作的颜色一样,于是我们将 \(dp\) 改成 \(f_{n,m,t,* }\) 表示有 \(t\) 中颜色不能作为一行或一列全部相同时的颜色,显然 \(t\in\{0,1\}\)
考虑下一个极长段,不妨设其是 \(A\) 操作的极长段,设此次操作了 \(r\) 行,方案数是 \((C-t)^r\),后续操作中不再有 \(t\) 的限制,所以从 \(f_{n-r,m,0,* }\) 转移过来。

但是为了保证这一段 \(A\) 是极长的,要求剩下的 \(n-r\) 行中不能有某一行的颜色全部相同,列同理,所以要记 \(f_{n,m,t,x,y}\)\(x,y\) 分别表示当前是否限定每一行(列)的颜色不能完全相同。发现 \(x,y\) 两个限制最多同时存在一个(如果同时存在两个的话就没有能操作的东西了)所以我们可以只记一个(下面只记列是否有限制),通过交换行列数来限定是行还是列,例如上边的转移被写作 \(f_{n,m,t,0}\leftarrow f_{m,n-r,0,1}\)

然后是 \(f_{n,m,t,1}\) 的转移,要求是没有一列的颜色全相同。分两类讨论,如果这 \(r\) 行本身的颜色就有不同的,肯定符合要求,方案数是 \((C-t)^r-(C-t)\),从 \(f_{m,n-r,0,1}\) 转移过来。如果这 \(r\) 行都相同,那要求这列其余部分不能全都是当前的这种颜色,这个状态就是 \(f_{m,n-r,1,1}\) 的限制,方案数是 \((C-t)\)

最后答案是 \(f_{n-i,m-j,1,0}+f_{m-j,n-i,1,1}\) 即考虑执行完最终第一次操作的那些之后的第一个极长段时 \(A\) 还是 \(B\)

代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;inline ll read(){ll s=0,k=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-') k=-1;c=getchar();}while(c>='0'&&c<='9'){s=(s<<3)+(s<<1)+(c^48);c=getchar();}return s*k;
}const int N=405,mod=998244353;
ll fac[2][N],f[N][N][2][2],C[N][N],K;
int n,m;void Add(ll &x,ll y){x+=y;if(x>=mod) x-=mod;
}ll dfs(int n,int m,int t,int c){if(f[n][m][t][c]>=0) return f[n][m][t][c];ll res=fac[t][n];if(c) Add(res,mod-(K-t));for(int i=1;i<n;i++){ll tmp=0;if(!c) Add(tmp,fac[t][i]*dfs(m,n-i,0,1)%mod);else{Add(tmp,(K-t)*dfs(m,n-i,1,1)%mod);Add(tmp,(fac[t][i]-(K-t)+mod)%mod*dfs(m,n-i,0,1)%mod);}Add(res,tmp*C[n][i]%mod);}return f[n][m][t][c]=res;
}int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);n=read();m=read();K=read();int S=max(n,m);K%=mod;if(K==0) K=mod;for(int i=0;i<=S;i++){C[i][0]=1;for(int j=1;j<=i;j++){C[i][j]=C[i-1][j];Add(C[i][j],C[i-1][j-1]);}}fac[0][0]=fac[1][0]=1;for(int i=1;i<=S;i++){fac[0][i]=fac[0][i-1]*K%mod;fac[1][i]=fac[1][i-1]*(K-1)%mod;}memset(f,-1,sizeof(f));ll ans=1;for(int i=1;i<n;i++)for(int j=1;j<m;j++)Add(ans,C[n][i]*C[m][j]%mod*(dfs(n-i,m-j,1,0)+dfs(m-j,n-i,1,1))%mod);(ans*=K)%=mod;printf("%lld",ans);return 0;
}

ARC193D Magnets

题面:

给两个长为 \(n\)\(01\) 序列 \(A,B\),每次可以选择一个位置让每个 \(1\) 都向选的位置靠近一位,若一个位置上有多个 \(1\) 认为是一个。问最少多少次操作能让 \(A\) 序列和 \(B\) 序列一样,或报告无解。\(n\leq 1e6\)

题解:

观察操作发现,如果我们操作在所有 \(1\) 前或所有 \(1\) 后,可以起到一个平移的效果,即 \(A\) 中所有 \(1\) 的相对位置不变,这启示我们算出 \(A,B\) 的差分数组 \(da,db\)。问题转化为要把 \(A\) 的差分数组变成和 \(B\) 的差分数组一样(删去所有 \(da_i=0\))。

考虑一次操作会导致 \(da\) 发生什么变化:如果操作在两个 \(1\) 中间,会导致 \(da_i-2\)(称为 \(X_i\) 操作);如果操作在某个 \(1\) 上,会导致 \(da_i,da_{i+1}\) 都减少 \(1\)(称为 \(Y_i\) 操作)。特别的,如果操作在第一个或最后一个 \(1\) 上,只会令 \(da_1-1\)\(da_m-1\)

先不考虑这两个特殊的操作,那么每次操作都会让 \(da\) 的总和 \(-2\),操作次数的总和就是 \(\frac{\sum da_i-\sum db_i}{2}\)。我们让 \(da_i\) 依次和 \(db_j\) 匹配,如果 \(da_i>db_j\) 那么我们一直 \(da_i-2\) 直到 \(da_i==db_j+1\) 我们让 \(da_i-1,da_{i+1}-1\),然后匹配 \(da_{i+1},db_{j+1}\),否则如果 \(da_i<db_j\) 就把 \(da_i\) 减成零。如果最后 \(db_j\) 有剩下的没有配上或者 \(da_{m+1}\)\(-1\) 了就不合法,我们就需要通过特殊操做尽量让他合法并保证次数最小。
要求最小次数,那我们只要执行尽量少的特殊操作就行了,因为别的操作都是 \(-2\) 而特殊操作是 \(-1\)

有结论,特殊操做只会在开头和结尾各最多做一次。
如果最开始一下做了两次特殊操作(不妨设是在开头做的),那么可以将其改为一个 \(X\) 操作并向左平移一位,这样更改后没有变化操作数,连绝对位置都没有变化,可以替换。
如果匹配了某个 \(da\)\(db\) 的前缀后 \(da_i\) 现在成了队头并对其做了一次特殊操作,那么考虑对 \(da_{i-1}\) 执行的操作,如果执行了 \(X_{i-1}\),可以替换为 \(Y_{i-1}\) 和对 \(i-1\) 是队头时的特殊操作,如果执行了 \(Y\) 操作类似,这样我们就把 \(i\) 这个位置的特殊操作前移了,以此类推,我们可以全部都移到最开始的位置做。

所以这题的做法就是枚举首尾是否进行特殊操作,然后按上述方式检测是否合法,同时统计操作次数。

代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;inline ll read(){ll s=0,k=1;char c=getchar();while(c>'9'||c<'0'){if(c=='-') k=-1;c=getchar();}while(c>='0'&&c<='9'){s=(s<<3)+(s<<1)+(c^48);c=getchar();}return s*k;
}const int N=1e6+5,inf=1e9+7;
int n;
char s[N],t[N];int solve(int pl,int pr,vector<int>A,vector<int>B){if(pl) for(int i=1;i<A.size();i++) A[i]--;if(pr) for(int i=0;i<A.size()-1;i++) A[i]++;vector<int>dx,dy;for(int i=1;i<A.size();i++)if(A[i]>A[i-1]) dx.push_back(A[i]-A[i-1]);for(int i=1;i<B.size();i++)if(B[i]>B[i-1]) dy.push_back(B[i]-B[i-1]);if(dy.size()>dx.size()) return inf;int j=0,op=0,ans=0;for(int i=0;i<dx.size();i++){dx[i]-=op;int d=dx[i];if(j<dy.size()&&dx[i]>=dy[j]){d-=dy[j];j++;}ans+=d+1>>1;op=d&1;}if(j<dy.size()||op) return inf;return ans+abs(A[0]+ans-B[0])+pl+pr;
}int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);int T=read();while(T--){n=read();scanf("%s",s+1);scanf("%s",t+1);vector<int>A,B;for(int i=1;i<=n;i++){if(s[i]=='1') A.push_back(i);if(t[i]=='1') B.push_back(i);}if(B.size()>A.size()){puts("-1");continue;}if(A.size()==1){printf("%d\n",abs(A[0]-B[0]));continue;}int ans=inf;for(int i=0;i<2;i++)for(int j=0;j<2;j++)ans=min(ans,solve(i,j,A,B));if(ans>inf/2) puts("-1");else printf("%d\n",ans);}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3 axios

默认情况下,vue中并没有对ajax进行封装的,所以我们需要下载安装第三方httpajax工具包---axios。 官方文档:https://axios-http.com/zh/docs/intro在项目**根目录**下打开终端,使用 npm或者yarn安装包# npm install axios yarn add axios 接着在src目录下创建一个utils/http…

vue3 项目编译打包

打包编译 不管我们使用的是vue-cli还是vite进行项目构建和管理,将来要进行项目的部署迁移到外网服务器时,都是需要使用打包后的项目代码,打包后的代码会进行压缩,并且只需要运行在http服务器下面即可。我们一般在公司里面往往使用nginx来运行打包后的web前端项目。# vite的…

SpringBoot3集成Mybatis

Mybatis Mybatis是一款优秀的持久层框架,支持自定义SQL,Mybatis可以通过简单的XML或注解来配置和映射原始类型、接口和Java对象为数据库中的记录 SpringBoot配置Mybatis 前提pom.xml中已经导入mybatis依赖<dependency><groupId>org.mybatis.spring.boot</grou…

搜维尔科技:灵巧手和手套,直观的控制尽在您的手掌之中

轻质手套可模仿您的动作,实现终极控制 我们将灵巧手与轻量级的影子手套相结合,为机器人操控和抓取创造了一种新的控制和自动化解决方案。机器人手结合了直观的控制和无与伦比的运动自由度,可以准确模仿您的动作,精确地完成复杂的任务。 用途和好处 1.最小的延迟让您轻松实现…

【硬件测试】基于FPGA的MSK调制解调系统系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR

1.算法仿真效果 本文是之前写的文章:《基于FPGA的MSK调制解调系统verilog开发,包含testbench,同步模块,高斯信道模拟模块,误码率统计模块》的硬件测试版本。在系统在仿真版本基础上增加了ila在线数据采集模块,vio在线SNR设置模块,数据源模块。硬件ila测试结果如下:(完整代码…

根据空域图信息构造飞机航线图以及飞行轨迹模拟matlab仿真

1.程序功能描述 空域图是指航空领域中的一种图形表示方式,它涵盖了空中交通管理所需要的各种信息,比如航线、导航点、飞行高度层、飞行限制等。空域图是航空人员进行飞行计划制定的重要工具。在本课题中,根据空域图信息构造飞机航线图以及飞行轨迹模拟matlab仿真。 2.…

基于MobileNet深度学习网络的活体人脸识别检测算法matlab仿真

1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)classs = 2; % 创建一个图像数据存储对象imdsTrain,用于从名为"Data"的文件夹及其子文件夹中读取图像数据。 % "…

2021年-PTA模拟赛-L1-8 编程团体赛(仅代码)

简单题,无解析没必要存进去再遍历数组,数组就起一个记忆的作用,我还没想到有什么优化的办法。AcCode: #include<bits/stdc++.h> using namespace std; int team[10010]; int main(){int winner = 0, max = 0, N;cin >> N;while(N--){int tid, id, g;scanf("…

[AI/GPT/综述] AI Agent的设计模式综述

【AI Agent】作为【AI应用层】的三大件(Prompt/RAG/Agent[MCP])之一, AI Agent的设计模式,作为未来或正在向AI开发转型的IT从业人员(开发人员/产品经理等),不得不深入研究研究。序:文由其一,随着大模型的发展,通用智能不断迭代升级,应用模式也不断创新,从简单的Prompt应…

2021年-PTA模拟赛-L1-7 整除光棍(C/C++思路)

除法竖式运算思路:在L1里面,那就不考虑大数运算了,列个竖式发现只需要每次得到除数之后输出,然后把余数乘10加1就可以进行下一轮运算了。 为什么说c/c++思路呢————java自带高精度运算,应该十行左右就可以搞定了。AcCode: #include<bits/stdc++.h> using namespac…

2021年-PTA模拟赛-L1-7 整除光棍(思路)

除法竖式运算思路:在L1里面,那就不考虑大数运算了,列个竖式发现只需要每次得到除数之后输出,然后把余数乘10加1就可以进行下一轮运算了。AcCode: #include<bits/stdc++.h> using namespace std; int main(){int x, t = 0, cnt = 0;cin >> x;while(t < x) t =…

记住密码和访问外部链接的实现

记住密码和访问外部链接的实现 今天的开发中实现了两项功能一个是记住密码,另外一个是可以访问外部链接. 记住密码 这个功能要使用到缓存技术,storage,uni中有自己的uni.stotageSync是同步的缓存技术,在登录成功跳转页面前把密码和用户名直接存储到缓存中, 在页面加载完成时在o…