Codeforces Round 956 (Div. 2)

news/2024/10/1 19:26:41

无法评价,不知道是我傻逼还是题傻逼。

A. Array Divisibility

题意

让你构造一个长度为 \(n\) 的序列,满足对于每一个 \(i\) \((i\in [1,n])\) ,让 \(a_j\) 之和为 \(i\) 的倍数, \(j\) 能被 \(i\) 整除。换句话说,让你构造一个长度为 \(n\) 的序列,满足 \(\sum_{j|i} a_j\) 能被 \(i\) 整除。

思路

这题很容易想到直接输出 \(1...n\) 即可。但是我被骗了。我当时想的是让每一个下标是 \(i\) 的倍数的位置都乘上 \(i\) ,时间复杂度 \(O(nlogn)\) 。而且还 \(\text{WA}\) 了一发,因为还要保证 \(a_i\leq 10^5\) 。赛后才想到 \(j\) 都保证是 \(i\) 的倍数了,那 \(\sum_{j|i}j\) 一定是 \(j\) 的倍数。真的唐完了。。。

代码

看看我的抽象代码

void solve()
{int n;cin>>n;vector<int> a(n+1,1);for(int i=1;i<=n;i++)for(int j=i;j<=n;j+=i){if(a[j]%i==0) continue;a[j]*=i;}for(int i=1;i<=n;i++) cout<<a[i]<<' ';cout<<endl;
}

B. Corner Twist

题意

给你一个初始矩阵和目标矩阵,每次操作你可以选择一个子矩阵,然后选择一个子矩阵的对角让这两个位置都加上 \(1\) ,剩下两个不选的位置都加上 \(2\) ,然后每个位置再对 \(3\) 取模。问你能不能从初始矩阵操作完变成目标矩阵。

思路

这题一开始我想的用目标矩阵对应的位置减去初始矩阵对应的位置然后获得了一个新的矩阵,这样就转化为把这个新的矩阵通过上面的操作让里面的数全部变成 \(0\) 。然后我以为这又是什么神秘的找规律结论题,然后我就对着样例开始找规律。一开始我以为只要我新的矩阵是一个中心对称图形就行,然后写了半天发现样例过不了,然后又以为只要他是一个斜对称图形就行,结果发现并不是。就这样我推了半个小时的结论。

最后发现,我只要枚举每个位置,选择的子矩阵大小为 \(2\times2\) 的,让这个位置变成 \(0\) 就行,不用管其他位置怎么样,如果操作到最后这个新的矩阵全部变成了 \(0\) 那么就是可以的,否则就是不行。

代码

void solve()
{int n,m;cin>>n>>m;int sum1=0,sum2=0;vector<string> a(n+1),b(n+1);for(int i=1;i<=n;i++){cin>>a[i];for(int j=0;j<a[i].size();j++) sum1+=(a[i][j]-'0');}vector mp(n+1,vector<int>(m+1));for(int i=1;i<=n;i++){cin>>b[i];for(int j=0;j<b[i].size();j++) sum2+=(b[i][j]-'0'),mp[i][j+1]=(b[i][j]-a[i][j]+3)%3;}auto change=[&](int i,int j,int op){   if(op==1){mp[i][j]=0;mp[i][j+1]++;mp[i][j+1]%=3;mp[i+1][j]++;mp[i+1][j]%=3;mp[i+1][j+1]+=2;mp[i+1][j+1]%=3;}if(op==2){mp[i][j]=0;mp[i][j+1]+=2;mp[i][j+1]%=3;mp[i+1][j]+=2;mp[i+1][j]%=3;mp[i+1][j+1]++;mp[i+1][j+1]%=3;}};int flag=0;for(int i=1;i<n;i++){for(int j=1;j<m;j++){if(mp[i][j]==1) change(i,j,1);else if(mp[i][j]==2)change(i,j,2);}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) if(mp[i][j])flag=1;}if(flag) cout<<"NO\n";else cout<<"YES\n"; 
}

C. Have Your Cake and Eat It Too

题意

三个人在分蛋糕,可以分成 \(n\) 块蛋糕,但是每个人对每块蛋糕的美味值不同。 \(\text{Alice}\) 认为第 \(i\) 块蛋糕的美味值为 \(a_i\), \(\text{Bob}\) 认为第 \(i\) 块蛋糕的美味值为 \(b_i\), \(\text{Charlie}\) 认为第 \(i\) 块蛋糕的美味值为 \(c_i\) 。现在让你给每个人分一块连续的蛋糕,还要保证这三个区间不相交,使得每个人获得的蛋糕美味度不低于 \(x\) 。请问是否存在一种合法的分法。

思路

贪心。从前往后遍历,如果这段区间的总和大于了 \(x\) 那就把下一段区间的蛋糕分给另一个人,直到全部分完为止。但是,分了三段区间,还要枚举每个人吃哪一段区间,所以还得分情况讨论六次。你知道我一个一个改有多麻烦吗(出题人真的是私募了)。如果有更好的写法欢迎留言。

代码

int tot;
pair<int,int> check(vector<int> &x,vector<int> &y,vector<int> &z)
{int n=x.size()-1;int l,r,num=(tot-1)/3+1,flag=0;for(l=1;l<=n;l++) if(x[l]>=num) {flag++;break;}for(r=l+1;r<=n;r++) if(y[r]-y[l]>=num) {flag++;break;}if(z[n]-z[r]>=num) flag++;if(flag==3) return {l,r};else return {0ll,0ll};
}
void solve()
{int n;cin>>n;vector<int> a(n+1),b(n+1),c(n+1);for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];for(int i=1;i<=n;i++) cin>>b[i],b[i]+=b[i-1];for(int i=1;i<=n;i++) cin>>c[i],c[i]+=c[i-1];tot=a[n]; int al=0,ar=0,bl=0,br=0,cl=0,cr=0;auto temp=check(a,b,c);if(temp.first) al=1,ar=temp.first,bl=temp.first+1,br=temp.second,cl=temp.second+1,cr=n;temp=check(a,c,b);if(temp.first) al=1,ar=temp.first,cl=temp.first+1,cr=temp.second,bl=temp.second+1,br=n;temp=check(b,a,c);if(temp.first) bl=1,br=temp.first,al=temp.first+1,ar=temp.second,cl=temp.second+1,cr=n;temp=check(b,c,a);if(temp.first) bl=1,br=temp.first,cl=temp.first+1,cr=temp.second,al=temp.second+1,ar=n;temp=check(c,a,b);if(temp.first) cl=1,cr=temp.first,al=temp.first+1,ar=temp.second,bl=temp.second+1,br=n;temp=check(c,b,a);if(temp.first) cl=1,cr=temp.first,bl=temp.first+1,br=temp.second,al=temp.second+1,ar=n;if(al) cout<<al<<' '<<ar<<' '<<bl<<' '<<br<<' '<<cl<<' '<<cr<<endl;else cout<<-1<<endl;
}

D. Swap Dilemma

题意

给你两个数组 \(a,b\) ,你每次可以选择一个 \(l,r,p,q\) ,满足 \(r-l+1=q-p+1\)。然后交换 \(a_l,a_r\) , 和 \(a_p,a_q\) 。 问你经过若干次操作之后能不能使得两个序列相等。

思路

这个题我想了一个小时都没想出来怎么做。因为我不知道要满足 \(r-l+1=q-p+1\) 这个条件该怎么交换。
但是首先要保证两个序列里的元素要一模一样才行。
之后我想到了 \(i\)\(a_i,b_i\) 连边构成两张图,然后考虑环个数的奇偶性,如果两个图环的奇偶性相同那么就是 YES。证明如下:

  • 如果交换的两个点在同一个环上,那么这个环会分裂成两个环。
  • 如果交换的点不在同一个环上,就等价于把这两个环合并成一个环。

所以只要经行交换操作,就会换改变环的个数。但是这个约束条件还是给我卡的死死的,到结束还是不知道怎么处理选取等距离的点。
看到别的题解说只需要选择两个相同的数交换即可,这使我恍然大悟,就像冒泡排序一样,\(a\) 序列中如果两个数想交换位置,只需要一直选择相邻的两个数,然后 \(b\) 序列里面任意选两个相邻的数左右横跳。这样就能把题目中的约束条件给消除了。


老老老老老师,我还有一种方法!

因为 \(a_i,b_i\) 中每个数都不相同,所以只要我们交换两个相邻的位置,那么这个序列里面逆序对的个数一定会加 \(1\) 或者减 \(1\) 。假设 \(b\) 序列反复横跳, \(a\) 序列可以任意交换两个位置的数使得 \(a\) 长得更像 \(b\) ,如果 \(a,b\) 初始的逆序对奇偶性不同那么无论如何都无法使得两个序列相等。所以判断一下 \(a,b\) 的逆序对奇偶性是否相等就可以了。

代码

方法一:

void solve()
{int n;cin>>n;vector<int> a(n+1),b(n+1),X,Y;for(int i=1;i<=n;i++) cin>>a[i],X.push_back(a[i]);for(int i=1;i<=n;i++) cin>>b[i],Y.push_back(b[i]);sort(X.begin(),X.end());sort(Y.begin(),Y.end());if(X!=Y) return cout<<"NO\n",void();vector<int> e1[n+1],e2[n+1];for(int i=1;i<=n;i++) e1[lower_bound(X.begin(),X.end(),a[i])-X.begin()+1].push_back(i);for(int i=1;i<=n;i++) e2[lower_bound(Y.begin(),Y.end(),b[i])-Y.begin()+1].push_back(i);int num1=0,num2=0;vector<int> vis1(n+1),vis2(n+1);for(int i=1;i<=n;i++){if(!vis1[i]){for(int j=i;;j=e1[j][0]) if(vis1[j]) break;else vis1[j]=1;num1++;}}for(int i=1;i<=n;i++){if(!vis2[i]){for(int j=i;;j=e2[j][0]) if(vis2[j]) break;else vis2[j]=1;num2++;}}if(num1%2==num2%2) cout<<"YES\n";else cout<<"NO\n";
}

方法二:


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

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

相关文章

19_深度图解剖析悲观锁与乐观锁两种并发控制方案

课程大纲 1、深度图解剖析悲观锁与乐观锁两种并发控制方案

js逆向实战之酷我音乐请求参数reqId加密逻辑

声明:本篇文章仅用于知识分享 实战网站:https://www.kuwo.cn/search/list?key=可以不是你 加密逻辑分析访问界面,根据数据包的回显内容判断哪个是我们需要的。找到相应的数据包,看下请求参数。发现reqId参数是一串随机字符串,所以就需要知道该参数的生成过程。全局搜索re…

13_图解Elasticsearch容错机制:master选举,replica容错,数据恢复

课程大纲 1、图解Elasticsearch容错机制:master选举,replica容错,数据恢复 (1)9 shard,3 node (2)master node宕机,自动master选举,red (3)replica容错:新master将replica提升为primary shard,yellow (4)重启宕机node,master copy replica到该node,使用原有的…

12_分布式原理_图解横向扩容过程,如何超出扩容极限,以及如何提升容错性

1、图解横向扩容过程,如何超出扩容极限,以及如何提升容错性 (1)primary&replica自动负载均衡,6个shard,3 primary,3 replica (2)每个node有更少的shard,IO/CPU/Memory资源给每个shard分配更多,每个shard性能更好 (3)扩容的极限,6个shard(3 primary,3 repli…

09_手工画图剖析Elasticsearch的基础分布式架构

课程大纲 1、Elasticsearch对复杂分布式机制的透明隐藏特性 2、Elasticsearch的垂直扩容与水平扩容 3、增减或减少节点时的数据rebalance 4、master节点 5、节点对等的分布式架构1、Elasticsearch对复杂分布式机制的透明隐藏特性 Elasticsearch是一套分布式的系统,分布式是为了…

10_shardreplica机制再次梳理以及单node环境中创建index图解

1、shard&replica机制再次梳理 2、图解单node环境下创建index是什么样子的1、shard&replica机制再次梳理 (1)index包含多个shard (2)每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力 (3)增减节点时,shard会自动在nod…

04_手工画图剖析Elasticsearch核心概念:NRT、索引、分片、副本等

课程大纲 1、lucene和elasticsearch的前世今生 2、elasticsearch的核心概念 3、elasticsearch核心概念 vs. 数据库核心概念1、lucene和elasticsearch的前世今生 lucene,最先进、功能最强大的搜索库,直接基于lucene开发,非常复杂,api复杂(实现一些简单的功能,写大量的java…

02_用大白话告诉你什么是Elasticsearch

大白话、什么是Elasticsearch Elasticsearch,分布式,高性能,高可用,可伸缩的搜索和分析系统 1、什么是搜索? 2、如果用数据库做搜索会怎么样? 3、什么是全文检索、倒排索引和Lucene? 4、什么是Elasticsearch?1、什么是搜索? 百度:我们比如说想找寻任何的信息的时候,…