Codeforces Round #655 (Div. 2) A-D完
Posted asanagiyantia
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #655 (Div. 2) A-D完相关的知识,希望对你有一定的参考价值。
A.
再三确认题目,可以出现重复数字后,全1输出即可。
B.
有x,将x分成a+b(a+b==x) 如何分配,使LCM(a,b)最小。
通过样例注意到偶数可以分成两个一样的数字
9可以分成x,2x。
然后毫无理由的猜测平方数可以分成x,2x,但是是完全错误的。
然后举了一些小的例子,比如7->(1,6),(2,5),(3,4)想着n为素数时只有1和n-1可以min(lcm(a,b))。那么,能不能找出所有素数呢?
还是不行
那么是不是和他的因数有关系呢?
35=57
(1,34)
...
(5,30)
(10,25)
(15,20)
诶,这里是10,25么?反而是(5,30)
那么是不是一个数字是另外一个的整数倍呢?
抱着这个是解的想法(虽然完全没有证明),开始做题了
要LCM(x,n-x),x|n-x,即n-x=xp,n=x*(p+1)
要min(x,n-x) 即 max(x),即min(p+1),(p>=1),那么就找n的最小素因数p+1,那么 x=n/(p+1),n-x也可以求出来了~
代码:
#include<iostream>
#define ll long long
using namespace std;
const long N = 200000;
ll prime[N] = {0},num_prime = 0;
int isNotPrime[N] = {1, 1};
int main()
{
for(int i = 2 ; i < N ; i ++) {if(! isNotPrime[i])prime[num_prime ++]=i;for(int j=0;j<num_prime&&i*prime[j]<N;j++) { isNotPrime[i*prime[j]]=1; if(!(i % prime[j])) break;} }
int t;
cin>>t;
while (t--){
int n;
cin>>n;
bool bo=true;
for (int i=0;i<num_prime;i++){
if (n%prime[i]==0){
cout<<n/prime[i]<<" "<<n-(n/prime[i])<<endl;
bo=false;
break;
}
}
if (bo) cout<<"1 "<<n-1<<endl;
}
return 0;
}
C.
一个乱序全排列,一次操作可以且尽可以
1.在一个连续区间
2.这个区间内的数必须改变
考虑到全部有序 0,两端有序1。
问题化简为i不在非两端,a[i]=i的情况
xjb乱猜一通,是不是先乱序再正序可以呢?
数学证明很麻烦
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int main(){
int t;
cin>>t;
while (t--){
int n;
cin>>n;
int a[maxn];
int s,t;
for (int i=1;i<=n;i++){
cin>>a[i];
}
a[0]=0; a[n+1]=n+1;
s=0; t=n+1;
while (a[s]==s && s<=n) s++;
while (a[t]==t && t>0) t--;
if (s==n+1) {cout<<"0
"; continue;}
bool bo2=false;
for (int i=s+1;i<t;i++) if(a[i]==i) {bo2=true; break;}
if (bo2) cout<<2<<endl;
else cout<<1<<endl;
}
}
D.
傻逼题
观察删的数,一定是间隔的。
所以是间隔删。
比如
1,2,3,4,5,6,7
就是环上删3个数字。
len=n的环变成[1,n]的2*n长度的序列。
求前缀和。
忘了ll瞬间爆炸
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5e5+10;
ll a[maxn];
ll nd[maxn],od[maxn];
int main(){
int n;
ll tot=0,sum1=0,sum2=0;
cin>>n;
for (int i=1;i<=n;i++) {cin>>a[i]; tot+=a[i];}
for (int i=n+1;i<=n*2;i++) a[i]=a[i-n];
for (int i=1;i<=n*2;i++)
if (i%2) od[i/2+1]=od[i/2]+a[i];
else nd[i/2]=nd[i/2-1]+a[i];
ll minn=LONG_LONG_MAX;
for (int i=n/2;i<=n;i++){
minn=min(minn,od[i]-od[i-n/2]);
minn=min(minn,nd[i]-nd[i-n/2]);
}
cout<<tot-minn<<endl;
}
以上是关于Codeforces Round #655 (Div. 2) A-D完的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #655 (Div. 2)
Codeforces Round #655 (Div. 2) A. Omkar and Completion
Codeforces Round #655 (Div. 2) D. Omkar and Circle
Codeforces Round #655 (Div. 2) A-D完