题解-比赛CF1332
题解-比赛CF1332
[A]Exercising Walk
\(T\) 组测试数据,每次给定 \(a,b,c,d,x,y,x_1,y_1,x_2,y_2\)。起点是 \((x,y)\),要左走 \(a\) 步,右走 \(b\) 步,下走 \(c\) 步,上走 \(d\) 步(这题的 \(x\) 和 \(y\) 轴与平时相反)。求是否有走法,使得走的过程中总是满足 \(x_1\le x\le x_2\),\(y_1\le y\le y_2\)。如果满足输出 \(\texttt{YES}\),否则输出 \(\texttt{NO}\)。
数据范围:\(1\le T\le 10^3\),\(0\le a,b,c,d\le 10^8\),\(a+b+c+d\ge 1\),\(-10^8\le x_1\le x\le x_2\le 10^8\),\(-10^8\le y_1\le y\le y_2\le 10^8\)。
本来以为直接找到最终点看看在不在范围内就够了,但是后来发现过不了样例。
有一种特殊情况:\([x_1=x]\&[x=x_2]\&[a,b>0]\&[a+b=0]\)(一走就走出范围了),答案是 \(\texttt{NO}\),你会输出 \(\texttt{YES}\)。
对于 \(y,c,d\) 同理,所以特判一下就过了。
易错点:
- 没看清这题的 \(x\) 和 \(y\) 轴与平时相反这个特点。
- 没考虑到特殊情况(你样例都过不了啊)。
代码:
//Data
int a,b,c,d,x,y,x1,y1,x2,y2;
il int yes(){
if(a&&b) if(x==x1&&x==x2) return 0;
if(c&&d) if(y==y1&&y==y2) return 0;
x-=a,x+=b,y-=c,y+=d;
return x1<=x&&x<=x2&&y1<=y&&y<=y2;
}
//Main
int main(){
re int t;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d%d%d%d%d%d%d",&a,&b,&c,&d,&x,&y,&x1,&y1,&x2,&y2);
if(yes()) puts("YES"); else puts("NO");
}
return 0;
}
[B]Composite Coloring
\(T\) 组测试数据,每次给定一个长度为 \(n\) 的合数序列 \(a_i\),需要将每个数染上颜色,使满足对于任意两个颜色相同的数不互质。求一种颜色数为 \(m\) 的染色方案(\(m\) 自选,不需最小,只需满足 \(m\in[1,11]\))。
数据范围:\(1\le T\le 10^3\),\(1\le n\le 10^3\),\(4\le a_i\le 10^3\),\(1\le \sum n\le 10^4\)。
对于任意满足数据范围限制的序列绝对有解。
对于任何合数 \(a_i\le 1000\),必然有 \(d\) 满足 \([d|i]\&[d<32]\)。
\([1,32)\) 中正好有 \(11\) 个质数,所以遍历每个质数然后把它们的倍数染同色即可。
易错点:
题目中有说对于 \(1\sim m\) 中的每个颜色,必须有该颜色的数,所以需要对颜色离散化。
代码:
//Data
const int N=1000;
int n,a[N+7],co[N+7];
//Prime
bitset<37> np;
vector<int> p;
//Main
int main(){
for(re int i=2;i<=32;i++){
if(!np[i]) p.pb(i);
for(re int j:p)if(i*j>N) break;else np[i*j]=1;
}
re int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(re int i=1;i<=n;i++)
scanf("%d",a+i);
re int C=0;
fill(co+1,co+n+1,0);
for(re int j:p){
re int ttt=0;
for(re int i=1;i<=n;i++){
if(!co[i]&&a[i]%j==0){ttt=1,co[i]=C+1;}
}
if(ttt) C++;
}
printf("%d\n",C);
for(re int i=1;i<=n;i++)
printf("%d%c",co[i],"\n "[i<n]);
}
return 0;
}
[C]K-Complete Word
\(T\) 组测试数据,给定 \(n\) 和 \(k\) 满足 \(k|n\),给定一个长度为 \(n\) 的字符串 \(s\),求最少修改 \(s\) 的几个字母,使得 \(s\) 是回文串并且对于所有 \(1\le i\le n-k\),满足 \(s_i=s_{i+k}\)。
数据范围:\(1\le t\le 10^5\),\(1\le k<n\le 2\times 10^5\),\(\sum n\le 2\times 10^5\)。
第二个条件等价于 \(s\) 的 \(\frac nk\) 个 \(k\) 长子段相等;因为 \(s\) 是回文的,所以每个 \(k\) 长子段也是回文的。
所以对于每个 \(1\le i\le \lfloor\frac k2\rfloor\),满足:
\]
如果 \(k\in \mathbb{odd}\),对于 \(i=\frac {k+1}2\) 满足:
\]
所以把每群相等的字符中出现次数最多的字符留着,把别的字符改成该字符即可。
代码:
//Data
const int N=200000;
int n,k;
char s[N+7];
int cnt[30];
//Main
int main(){
re int t;
scanf("%d",&t);
while(t--){
scanf("%d%d\n%s",&n,&k,s+1);
re int ans=0;
for(re int i=1;i<=k/2;i++){
memset(cnt,0,sizeof cnt);
re int tmp=0;
for(re int j=i;j<=n;j+=k) cnt[s[j]-'a']++,tmp++;
for(re int j=k+1-i;j<=n;j+=k) cnt[s[j]-'a']++,tmp++;
re int mx=0;
for(re int i=1;i<26;i++) if(cnt[i]>cnt[mx]) mx=i;
ans+=tmp-cnt[mx];
}
if(k&1){ //k∈odd
int i=(k+1)/2;
memset(cnt,0,sizeof cnt);
re int tmp=0;
for(re int j=i;j<=n;j+=k) cnt[s[j]-'a']++,tmp++;
re int mx=0;
for(re int i=1;i<26;i++) if(cnt[i]>cnt[mx]) mx=i;
ans+=tmp-cnt[mx];
}
printf("%d\n",ans);
}
return 0;
}
[D]Walk on Matrix
给定一个 \(k\),要求构造一个随意大小为 \(n\times m\) 的矩阵 \(a_{i,j}\) 使得用
得到的答案与从 \((1,1)\) 到 \((n,m)\) 的最小按位与路径答案相差 \(k\)。
数据范围:\(1\le n,m\le 500\),\(0\le a_{i,j}\le 3\cdot 10^5\),\(0\le k\le 10^5\)。
很巧妙的一题,从数据范围以及样例中可以猜测到这题有通解。
首先这个答案 \(S\) 肯定是比真实答案 \(Ans\) 大的,所以 \(S-Ans=k\)。
通过研究第二个样例,可以发现,鲍勃的代码会盲目找最大的,不会考虑如 \(7\&3>8\&3\) 的情况。
所以可以找一个 \(t=2^c>k\),构造如下 \(3\times 4\) 矩阵:
t|k&k&k&0\\
t&0&k&0\\
t&t&t|k&k\\
\end{bmatrix}
\]
所以鲍勃的代码 \(dp_{3,3}=t,dp_{3,4}=0\)。
而真正的最小按位与路径为 \((t|k)\&k\&k\&k\&(t|k)\&k\),答案为 \(k\)。
正好相差 \(k\)。
代码:
//Data
//Main
int main(){
re int k,t=1;
scanf("%d",&k);
while(t<=k) t<<=1;
printf("3 4\n");
printf("%d %d %d %d\n",t|k,k,k,0);
printf("%d %d %d %d\n",t,0,k,0);
printf("%d %d %d %d\n",t,t,t|k,k);
return 0;
}
[E]Height All the Same
给定 \(n,m,L,R\),求大小为 \(n\times m\) 的矩阵 \(a_{i,j}\) 中满足 \(L\le a_{i,j}\le R\) 并且可以通过相邻元素一起 \(+1\)、元素 \(+2\) 两种操作使整个矩阵相等的数量 \(\bmod 998244353\)。
数据范围:\(1\le n,m,L,R\le 10^9\),\(L\le R\)。
很明显 \(L\) 和 \(R\) 的绝对大小不重要,所以设 \(H=R-L+1\)。
如果没有后一个限制,答案应该是 \(H^{nm}\)。
手玩几下会发现,只要奇偶性满足要求,该矩阵就满足要求,所以:
- 如果 \(nm\in\mathbb{odd}\):答案就为 \(H^{nm}\)。
- 如果 \(nm\in\mathbb{even}\):答案就为 \(\lceil\frac{H^{nm}}{2}\rceil\)。
易错点:
- 要 \(\bmod 998244353\),除法用逆元,幂 \(\bmod 998244352\)(欧拉定理)。
- 快速幂的时候,因为可能 \(H\bmod 998244353=0\),如果 \(nm\bmod 998244352=0\),普通人写的快速幂很容易得到 \(1\),其实应该得到 \(0\)(因此我 \(FST\) 了)。
代码:
//Data
const int Mo=998244353;
int n,m,a,b,h;
lng sz;
il int Pow(re int a,re int x){
if(a==0) return 0;
re int res=1;
for(;x;a=1ll*a*a%Mo,x>>=1)if(x&1)res=1ll*res*a%Mo;
return res;
}
//Main
int main(){
scanf("%d%d%d%d",&n,&m,&a,&b);
h=b-a+1,sz=1ll*n*m;
if(sz&1) printf("%lld\n",1ll*Pow(h,sz%(Mo-1)));
else if(h&1) printf("%lld\n",1ll*(Pow(h%Mo,sz%(Mo-1))+1+Mo)%Mo*Pow(2,Mo-2)%Mo);
else printf("%lld\n",1ll*Pow(h%Mo,sz%(Mo-1))*Pow(2,Mo-2)%Mo);
return 0;
}
[F]Independent Set
给定树 \(G=(V,E)\),\(n\) 个点。令 \(E'\in E\),求所有 \(E'\) 所有边两端的节点的独立集数量之和 \(\bmod 998244353\)(独立集大小可以为 \(0\),\(E'\neq\varnothing\))。
数据范围:\(2\le n\le 3\times10^5\)。
这么简单的树形 \(\texttt{dp}\) 我竟然不会,而且想了好久,我太蒻了。
设 \(f_{o,i}\) 表示:
- 如果 \(o=0\):\(i\) 点选或不选都可以,但是连接 \(i\) 号点与父亲节点的边不存在的 \(i\) 的子树中的答案。
- 如果 \(o=1\):\(i\) 点不选,连接 \(i\) 号点与父亲节点的边存在的 \(i\) 的子树中的答案。
- 如果 \(o=2\):\(i\) 点选,连接 \(i\) 号点与父亲节点的边存在的 \(i\) 的子树中的答案。
以上“答案”均包括选的边为空的情况。
如果该节点选,子节点不与该节点连边或者不选是允许的:
\]
如果该节点不选,子节点怎么样都是允许的:
\]
如果该节点不与父亲节点连边,包括选或不选的情况,但是要排除所有子节点都不与该节点连边的情况(要不然节点孤立,就不是边两端的点了):
\]
因为答案不应包括选的边为空的情况,而且根节点不与父亲节点连边(根节点的父亲节点不存在),所以最终答案为 \(f_{0,1}-1\)。
代码:
//Data
const int N=300000,m=998244353;
int n;
vector<lng> f[3];
vector<vector<int> > e;
//Dfs
il void Dfs(re int x,re int fa){
f[0][x]=f[1][x]=f[2][x]=1;
for(re int to:e[x])if(to!=fa){
Dfs(to,x);
(f[0][x]*=f[0][to])%=m;
(f[1][x]*=(f[0][to]+f[1][to]+f[2][to]))%=m;
(f[2][x]*=(f[0][to]+f[1][to]))%=m;
}
f[0][x]=(f[1][x]+f[2][x]-f[0][x]+m)%m;
}
//Main
int main(){
scanf("%d",&n);
e.resize(n+7);
for(re int i=0;i<3;i++) f[i].resize(n+7);
for(re int i=1,u,v;i<n;i++)
scanf("%d%d",&u,&v),e[u].pb(v),e[v].pb(u);
Dfs(1,0);
printf("%lld\n",(f[0][1]+m-1)%m);
return 0;
}
未完待续
祝大家学习愉快!
题解-比赛CF1332的更多相关文章
- 题解 比赛 match
比赛 match Description 有 N 支队伍打比赛.已知有如下条件: • 每支队伍恰好打了 4 场比赛 • 对于一场比赛,如果是平局,双方各得 1 分:否则胜者得 3 分,负者不得分 给定 ...
- AtCoder Grand Contest 031题解
题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...
- ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (贪心或有源汇上下界网络流)
"Oh, There is a bipartite graph.""Make it Fantastic."X wants to check whether a ...
- hdu 5616
Jam's balance Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- 湖南大学第十四届ACM程序设计新生杯 E.Easy Problem
E.Easy Problem Description: Zghh likes number, but he doesn't like writing problem description. So h ...
- (寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)
layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa&q ...
- ACM2016级新生第三周训练赛
本次是弱校题解-比赛链接 备用链接 题目还是比较基础,比较简单.认真补题,学会学习. A -人见人爱A^B 题解: 求 A的B次方,我们可以用循环进行累乘操作,进而计算出次方.因为题目要求只需要求出最 ...
- P5162 WD与积木(多项式求逆+生成函数)
传送门 题解 比赛的时候光顾着算某一个\(n\)的答案是多少忘了考虑不同的\(n\)之间的联系了--而且我也很想知道为什么推着推着会变成一个二项式反演-- 设\(f_n\)为\(n\)块积木时的总的层 ...
- upc组队赛4 TV Show Game 【2-SAT】
TV Show Game 题目描述 Mr. Dajuda, who is famous for a TV show program, occasionally suggests an interest ...
随机推荐
- 这些表情包你有吗?来 Battle 啊
"能用表情包解决的问题,绝不多说一个字." "当不知道回复什么的时候,甩过去一个表情包就好了." 放眼望去,谁的 QQ/微信 收藏中没有几页代表性的表情包,那真 ...
- Linux程序开发中如何判断目录是否为根目录?
问题引入 判断某个目录字符串是否是根目录,咋一听很简单,只要判断字符串是否是"/"即可,但是,很多情况下使用的路径是相对路径,那么如何判断相对路径是根目录呢? 思路分析 熟悉Lin ...
- Ceph如何实现文件系统的横向扩展
前言 在跟一个朋友聊天的时候,聊到一个技术问题,他们的一个环境上面小文件巨多,是我目前知道的集群里面规模算非常大的了,但是目前有个问题,一方面会进行一倍的硬件的扩容,而文件的数量也在剧烈的增长着,所以 ...
- 解决IE下readonly的Input光标选中的问题
首先用unselectable="on"解决,但是这种方法bug太多, 屏蔽了input的onblur事件(也就是focus事件在Angualr下),所以只能用click事件来代替 ...
- 《Spring Boot 实战纪实》之需求管理
目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...
- css中渐变的分割线和自定义滚动条样式
css中渐变的分隔线: <div style="background:linear-gradient(to left,#efefef,#b6b6b6,#efefef);height:1 ...
- 这份java多线程笔记,你真得好好看看,我还没见过总结的这么全面的
1.线程,进程和多线程 1.程序:指指令和数据的有序集合,其本身没有任何意义,是一个静态的概念 2.进程:指执行程序的一次执行过程,是一个动态的概念.是系统资源分配的单位(注意:很多多线程是模拟出来的 ...
- 系统兼容软件CrossOver和虚拟机软件,哪个好用?
想要在Mac上运行Windows软件的方法有很多种,比较常见的有安装双系统以及虚拟机.但是安装双系统会导致一个很大的问题,就是占用了过多的硬盘空间,这样一来会导致可使用的空间减少. 目前来说,大家都不 ...
- 能否安装 CrossOver 上没有的软件
系统兼容软件CrossOver可以像虚拟机一下帮助我们在Mac或者Linux上运行Windows应用程序,快速实现跨平台文件互通,所以我们也称它为类虚拟机. 不需要安装Windows操作系统的Cros ...
- 紧急发布用cherry-pick检出当前分支所有我的提交记录
目录 背景 操作命令 cherry-pick git log Shell脚本 背景 公司接了个新项目,需在平台上增加几个新接口,问题是本来说是和平台一起迭代发布的时间提前了,但当前的代码都和其他开发人 ...