Codeforces Round #752 (Div. 2)
历史新高!!
A. Era
思路:一开始想歪了,以为是找一个最大数的下标然后输出最大数减去最大数下标。后来用数据 1 1 5 1 6 hack掉了这个想法,就很明显的发现到其实只要枚举一遍,存最大的$a[i]-idx$即可。
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int a[N];
#define snow ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using ll=long long ;
void solve(){
int n;
cin>>n;
int MA=-2e9;
for(int i=1;i<=n;i++){
cin>>a[i];
MA=max(MA,a[i]-i);
}
cout<<max(0,MA)<<endl;
}
int main(){
snow;
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
B. XOR Specia-LIS-t
思路:因为要求最后所有分段的$LIS$的$xor$值为0,那么显然如果$n$的数量为偶数,我们可以单独让每两个数两两配对,最后形成偶数对,每一对的$xor$值都为1,那么偶数对$xor$最终的值必然为$0$,如果$n$的数量为奇数,那么我们只需要在$a$数组中找到两个相邻的并且组合形成的序列是非上升序列的数,那么这两个数组成的$h$值仍然为$1$,那么就回归到了上述的$n$为偶数的情况。
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N];
#define snow ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using ll=long long ;
void solve(){
int n;
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
if(n%2==0){
cout<<"YES"<<endl;
return ;
}
else{
int success=0;
for(int i=1;i<n;i++){
if(a[i]<=a[i-1]){success=1;break;}
}
if(success)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
int main(){
snow;
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
C. Di-visible Confusion
思路:我是向筛法的方向思考,将数组$a$枚举一遍,如果当前$a[i]$能被$idx+1,idx,idx-1 … 1+1$中任意一个筛掉也就是$a[i]\bmod idx+1!=0$说明这个数是一定能被筛掉的。为什么可以是其下标及前面任意一个位置呢?为什么不是判断其下标后面呢?证明:$1:$后面的数如果被筛掉,所有在这个被筛数后面的数下标减$1$不会影响到前面的数,所以不用判断前面这个数的后面下标。$2:$为啥判断其及其前面的下标呢?因为这个数前面的数如果被筛掉,那么它是有可能处在前面任一位置,而在前面任一位置被筛掉说明这个数一定能被 $remove$ $i$n $a$。那么就是枚举了,看似是$O(n^2)$的复杂度,但是细想一下会发现这个数只要 $mod$ $idx+1 !=0$就可以直接$break$掉,而且这个条件是非常弱的容易实现$break$。例如:如果数的下标非常大是$1e5$级别,那么什么数能够做到同时 $mod$ $1e5 和1e5-1 和1e5-2=0?$或者再来个$1e5-3?$所以条件非常弱远远达不到$O(n^2)$的复杂度。
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
#define snow ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using ll=long long ;
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
bool success=false;
for(int j=i;j>=1;j--){
int x=j+1;
if(a[i]%x!=0){
success=true;
break;
}
}
if(success==false){
cout<<"NO"<<endl;
return ;
}
}
cout<<"YES"<<endl;
return ;
}
int main(){
snow;
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
D. Moderate Modular Mode
思路:分三种情况讨论,$1: X==Y$,那么显然我们取$n$为$X$ $or$ $Y$都可,因为$n$ $mod$ $X==$ $Y$ $mod$ $n==0$。$2:X < Y$,我们只需要取$n=X*Y+Y$即可同样非常好想。$3:X>Y$,很多人在这里直接让$n=(X+Y)/2$但是显然是错误的$hack$数据$4$和$18$,如果取$n=(X+Y)/2$,那么$n=11$显然是错误的,容易发现如果$X=16$和$Y=18$的话取$n=(X+Y)/2=17$显然是对的,所以正确做法就是将前者$X$以倍数关系放大到不超过$Y$的最大形式即可,那么正确做法就是取$n=Y-Y$$mod$ $X/2$即可。
- 参考代码:
#include<bits/stdc++.h>
using namespace std;
#define snow ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using ll=long long ;
void solve(){
ll a,b;
cin>>a>>b;
if(a>b){
ll res;
res=a*b+b;
cout<<res<<endl;
}
else if(a==b){
cout<<a<<endl;
}
else{
cout<<b-b%a/2<<endl;
}
}
int main(){
snow;
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
强强强!
😁
Orz
谢谢大佬orz!!