# Codeforces Round 665 赛后解题报告

## A. Distance and Axis

$\mid(n-x)-x\mid=k$

$\mid n-2\cdot x \mid=k$

//Don't act like a loser.
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
#define int long long
using namespace std;

char ch=getchar();
int f=1,x=0;
while(ch<'0'||ch>'9') {
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}

int n,k;

signed main() {

while(T--) {

if(n<k) {
cout<<k-n<<endl;
}
else {
cout<<(n-k)%2<<endl;
}
}
return 0;
}



## B. Ternary Sequence

//Don't act like a loser.
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
#define int long long
using namespace std;

char ch=getchar();
int f=1,x=0;
while(ch<'0'||ch>'9') {
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}

int x[2],y[2],z[2];

signed main() {
while(T--) {
for(int i=0;i<=1;i++) {
}

int ans=0;

int tmp=min(z[1],x[0]);
z[1]-=tmp;
x[0]-=tmp;
if(z[1]) {
int t1=min(z[1],z[0]);
z[1]-=t1;
z[0]-=t1;
if(z[1]) {
ans-=z[1]*2;
y[0]-=z[1];
}
}

ans+=min(z[0],y[1])*2;

cout<<ans<<endl;
}
return 0;
}



## C. Mere Array

In one operation, you can choose two different indices $i$ and $j$ ($1\leq i$,$j\leq n$). If $\gcd(a_i,a_j)$ is equal to the minimum element of the whole array a, you can swap $a_i$ and $a_j$

//Don't act like a loser.
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
#define int long long
using namespace std;

char ch=getchar();
int f=1,x=0;
while(ch<'0'||ch>'9') {
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}

const int maxn=1e5+10;

int n,a[maxn],divi,b[maxn];

signed main() {

while(T--) {
divi=1e9+10;
for(int i=1;i<=n;i++) {
b[i]=a[i];
divi=min(divi,a[i]);
}

sort(b+1,b+n+1);//排序

bool flag=1;
int pos=0;
for(int i=1;i<=n;i++) {
if(a[i]%divi!=0) {
pos=upper_bound(b+1,b+i+1,a[i])-b;
if(!(pos-1==i&&b[pos-1]==a[i])) {//如果 $a_i$=$a_{i-1}$，我们的要特殊处理
printf("NO\n");
flag=0;
break;
}
}
}
if(flag) {
printf("YES\n");
}
}
return 0;
}



## D. Maximum Distributed Tree

$\sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^{n} f(i,j)=\sum\limits_{(u,v\in E)}con_{(u,v)}\times w_{(u,v)}$

• 如果 $m<n-1$ 那么一定会有边权为 $1$ 的边出现。那么为了让 $1$ 最少（题目要求），我们只有唯一解
• 否则我们可以让一些质因子合并，构造出 $n-1$ 个边权。那么我们为了让答案最大，一定是把最大的 $m-n+2$ 个边权堆在一起。证明很简单，就是因为如果我们有 $a>b,k>0$，那么 $k\cdot a>k\cdot b$。最后给 $w,con$ 数组排个序即可。

//Don't act like a loser.
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
#include<bits/stdc++.h>
#define int long long
using namespace std;

char ch=getchar();
int f=1,x=0;
while(ch<'0'||ch>'9') {
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}

const int maxn=1e5+10,mod=1e9+7;

int n,m;
int p[maxn],a[maxn],h[maxn],cnt,w[maxn],sz[maxn],con[maxn],tot;

struct edge {
int v,next;
}e[maxn<<1];

e[++cnt].v=v;
e[cnt].next=h[u];
h[u]=cnt;
}
void insert(int u,int v) {
}

void dfs(int u,int fa) {
sz[u]=1;
for(int i=h[u];i;i=e[i].next) {
int v=e[i].v;

if(v!=fa) {
dfs(v,u);
sz[u]+=sz[v];
}
}
if(fa!=0) {
con[++tot]=sz[u]*(n-sz[u]);//不着急取模
}
}

signed main() {
while(T--) {
fill(h+1,h+n+1,0);
cnt=0;
for(int i=1;i<n;i++) {
}
fill(w,w+n+1,0);
for(int i=1;i<=m;i++) {
}
sort(p+1,p+m+1);//这里要先排序

if(n-1<m) {//第一种
for(int i=1;i<n-1;i++) {
w[i]=p[i];
}
w[n-1]=p[n-1];
for(int i=n;i<=m;i++) {
w[n-1]=w[n-1]*p[i]%mod;
}
}
else {//第二种
for(int i=1;i<=m;i++) {
w[i]=p[i];
}
for(int i=m+1;i<n;i++) {
w[i]=1;
}
sort(w+1,w+n);
}

tot=0;
dfs(1,0);//维护con

int ans=0;

sort(con+1,con+n);
for(int i=1;i<n;i++) {
ans+=con[i]%mod*w[i]%mod;//贪心
ans%=mod;
}
cout<<ans<<endl;
}
return 0;
}



posted @ 2020-08-22 15:39  huayucaiji  阅读(229)  评论(0编辑  收藏  举报