Codeforces Round #752 (Div. 2)
历史新高!!
A. Era
思路:一开始想歪了,以为是找一个最大数的下标然后输出最大数减去最大数下标。后来用数据 1 1 5 1 6 hack掉了这个想法,就很明显的发现到其实只要枚举一遍,存最大的 a [ i ] − i d x a[i]-idx 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
思路:因为要求最后所有分段的 L I S LIS LIS的 x o r xor xor值为0,那么显然如果 n n n的数量为偶数,我们可以单独让每两个数两两配对,最后形成偶数对,每一队的 x o r xor xor值都为1,那么偶数对 x o r xor xor最终的值必然为 0 0 0,如果 n n n的数量为奇数,那么我们只需要在 a a a数组中找到两个相邻的并且组合形成的序列是非上升序列的数,那么这两个数组成的 h h h值仍然为 1 1 1,那么就回归到了上述的 n n 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 a枚举一遍,如果当前 a [ i ] a[i] a[i]能被 i d x + 1 , i d x , i d x − 1...1 + 1 idx+1,idx,idx-1 ... 1+1 idx+1,idx,idx−1...1+1中任意一个筛掉也就是 a [ i ] m o d i d x + 1 ! = 0 a[i]\bmod idx+1!=0 a[i]modidx+1!=0说明这个数是一定能被筛掉的。为什么可以是其下标及前面任意一个位置呢?为什么不是判断其下标后面呢?证明: 1 : 1: 1:后面的数如果被筛掉,所有在这个被筛数后面的数下标减 1 1 1不会影响到前面的数,所以不用判断前面这个数的后面下标。 2 : 2: 2:为啥判断其及其前面的下标呢?因为这个数前面的数如果被筛掉,那么它是有可能处在前面任一位置,而在前面任一位置被筛掉说明这个数一定能被 r e m o v e remove remove i i in a a a。那么就是枚举了,看似是 O ( n 2 ) O(n^2) O(n2)的复杂度,但是细想一下会发现这个数只要 m o d mod mod i d x + 1 ! = 0 idx+1 !=0 idx+1!=0就可以直接 b r e a k break break掉,而且这个条件是非常弱的容易实现 b r e a k break break。例如:如果数的下非常大是 1 e 5 1e5 1e5级别,那么什么数能够做到同时 m o d mod mod 1 e 5 和 1 e 5 − 1 和 1 e 5 − 2 = 0 ? 1e5 和1e5-1 和1e5-2=0? 1e5和1e5−1和1e5−2=0?或者再来个 1 e 5 − 3 ? 1e5-3? 1e5−3?所以条件非常弱远远达不到 O ( n 2 ) O(n^2) O(n2)的复杂度。
- 参考代码:
#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 1: X==Y 1:X==Y,那么显然我们取 n n n为 X X X o r or or Y Y Y都可,因为 n n n m o d mod mod X = = X== X== Y Y Y m o d mod mod n = = 0 n==0 n==0。 2 : X < Y 2:X<Y 2:X<Y,我们只需要取 n = X ∗ Y + Y n=X*Y+Y n=X∗Y+Y即可同样非常好想。 3 : X > Y 3:X>Y 3:X>Y,很多人在这里直接让 n = ( X + Y ) / 2 n=(X+Y)/2 n=(X+Y)/2但是显然是错误的 h a c k hack hack数据 4 4 4和 18 18 18,如果取 n = ( X + Y ) / 2 n=(X+Y)/2 n=(X+Y)/2,那么 n = 11 n=11 n=11显然是错误的,容易发现如果 X = 16 X=16 X=16和 Y = 18 Y=18 Y=18的话取 n = ( X + Y ) / 2 = 17 n=(X+Y)/2=17 n=(X+Y)/2=17显然是对的,所以正确做法就是将前者 X X X以倍数关系放大到不超过 Y Y Y的最大形式即可,那么正确做法就是取 n = Y − Y n=Y-Y n=Y−Y m o d mod mod X / 2 X/2 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;
}