Codeforces Round #665 (Div. 2)

过了千人题的坎,后面的题做不动了。还是菜。

唉,看着自己排名一直掉。

球球你们不要过题了。

球球不要 (FST)

心塞,还是太菜了。

能不能上个紫,求求了。

A. Distance and Axis

开始看错了题目,以为要求解

题意:

(A) 点的横坐标 (A_x = n) , 与整数 (k) ,问最少操作多少次使得存在一个整数点 (B) 使得 (|OB|)(|AB|) 的距离之差为 (k)

cin >> n >> k;

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

B. Ternary Sequence

题意:

序列 (a) , (b)(0,1,2) 组成。给出其个数 (x_1,y_1,z_1,x_2,y_2,z_2) ,重新组织(a) , (b)

得到序列 (c)

[c_i = egin{cases} a_i b_i & mbox{if }a_i > b_i \ 0 & mbox{if }a_i = b_i \ -a_i b_i & mbox{if }a_i < b_i end{cases} ]

求 $Max(sum c) $

思路:

观察后发现只有 a = 2,b = 1能有正数,a = 1,b = 2 为负数。

所以使得 (21) 尽可能多, (12) 尽可能少即可

cin >> T;
while(T--){
    int x1,y1,z1,x2,y2,z2;
    cin >> x1 >> y1 >> z1;
    cin >> x2 >> y2 >> z2;
    int ans = 0;
    ans += min(z1,y2);
    z1-=min(z1,y2);y2-=min(z1,y2);

    if(z2>x1+z1){
        ans-=z2-x1-z1;
    }
    cout << 2*ans << endl;
}

C. Mere Array

题意:

给一个正整数序列 (a)

$if gcd(a_i,a_j) = Min(a) $

则可以互换位置。

问能否经过若干次操作使得 (a) 非降序

思路:

设最小元素为 (m) ,对于所有的 (m) 的倍数, (m) 可以与这些元素互换

而这些元素之间也可以借助 (m) 完成互换

所有对与不是 (m) 的倍数的数,看排个序后是否还是一样

/* Author: coding_like_cxk
 * Time: 2020-08-21 22:35:03
**/

#include<bits/stdc++.h>
//#define int long long
using namespace std;

const int maxn = 2e5 + 10;
typedef long long ll;

int A[maxn];
int B[maxn];
int vis[maxn];

int T,n,m,k,a,b,c;
string s;

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> T;
    while(T--){
        cin >> n;
        memset(vis,0,sizeof(int)*(n+10));
        for(int i = 1;i <= n;i++){
            cin >> A[i];B[i] = A[i];
        }

        int Min = *min_element(A+1,A+1+n);
        for(int i = 1;i <= n;i++){
            if(A[i] % Min != 0){
                vis[i] = 1;
            }
        }

        sort(A+1,A+1+n);

        int f = 1;
        for(int i = 1;i <= n;i++){
            if(vis[i] && A[i] != B[i]){
                f = 0;
                break;
            }
        }
        string ans[2] = {"NO","YES"};
        cout << ans[f] << endl;
    }

}

D. Maximum Distributed Tree

题意:

给一棵树,要你分配边权。

使得边权为正整数且乘积为 (k) ,且 (1) 的数目要尽可能的少

问所有点之间的距离之和的最大可能值是多少,答案对 (1e9+7) 取模

思路:

先处理每条边的贡献,然后处理 (k) 的所有质因数,先排个序,若不足 (n-1)

,则后面用 (1) 填充。 若比 (n - 1) 多,则前面多出来的全部乘起来。

/* Author: coding_like_cxk
 * Time: 2020-08-21 22:35:03
**/

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int mod = 1e9 + 7;
const int maxn = 2e5 + 10;
typedef long long ll;

struct Edge {
	int to, next;
}E[maxn];
int head[maxn], tot;
void addEdge(int from, int to) {
	E[tot] = Edge{ to,head[from] };
	head[from] = tot++;

	E[tot] = Edge{ from,head[to] };
	head[to] = tot++;
}


int p[maxn];
int T, n, m, k, a, b, c;
string s;

vector<int>L;

int dfs(int now, int pre) {

	if (E[head[now]].to == pre && E[head[now]].next == -1) {
		L.push_back(n - 1);
		return 1;
	}

	int sum = 1;
	for (int i = head[now]; i != -1; i = E[i].next) {
		int to = E[i].to;
		if (to == pre)continue;

		sum += dfs(to, now);
	}
	if (now != 1) {
		L.push_back(sum * (n - sum));
	}
	return sum;
}


signed main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> T;
	while (T--) {
		cin >> n;
		memset(head, -1, sizeof(int) * (n + 10));
		L.clear();

		for (int i = 1; i <= n - 1; i++) {
			cin >> a >> b;
			addEdge(a, b);
		}

		cin >> m;

		for (int i = 1; i <= m; i++) {
			cin >> p[i];
		}

		sort(p + 1, p + 1 + m,greater<int>());
		dfs(1, -1);

		sort(L.begin(), L.end(),greater<int>());
		int d = 0;
		if (m > n - 1) {
			d = m - n + 1;
			for (int i = 1; i <= d; i++) {
				p[i + 1] = p[i + 1] * p[i] % mod;
			}
		}
		if (m < n - 1) {
			for (int i = m + 1; i <= n - 1; i++) {
				p[i] = 1;
			}
		}

		int ans = 0;
		for (int i = 1; i <= n - 1; i++) {
			ans += p[i + d] * L[i - 1];
			ans = (ans + mod) % mod;
		}

		cout << ans << endl;
	}

}

E. Divide Square

扫描线

(待补)也许吧

F. Reverse and Swap

魔改线段树 or 异或掩码
(待补)也许吧

200多rank了,大概是无缘紫名了吧。

淦!

原文地址:https://www.cnblogs.com/sduwh/p/13544019.html