1. 程式人生 > 其它 >Codeforces Round #781 (Div. 2)題解

Codeforces Round #781 (Div. 2)題解

A. GCD vs LCM

You are given a positive integer nn. You have to find 44 positive integers a,b,c,da,b,c,d such that

  • a+b+c+d=na+b+c+d=n, and
  • gcd(a,b)=lcm(c,d)gcd(a,b)=lcm⁡(c,d).

If there are several possible answers you can output any of them. It is possible to show that the answer always exists.

In this problem 

gcd(a,b)gcd(a,b) denotes the greatest common divisor of aa and bb, and lcm(c,d)lcm⁡(c,d) denotes the least common multiple of cc and dd.

Input

The input consists of multiple test cases. The first line contains a single integer tt (1t1041≤t≤104) — the number of test cases. Description of the test cases follows.

Each test case contains a single line with integer nn (4n1094≤n≤109) — the sum of aabbcc, and dd.

Output

For each test case output 44 positive integers aabbccdd such that a+b+c+d=na+b+c+d=n and gcd(a,b)=lcm(c,d)gcd(a,b)=lcm⁡(c,d).

題目大意:給定一個n,求出四個數a,b,c,d滿足a+b+c+d=n並且gcd(a,b)=gcd(c,d)。

思路:將一個數定義為n-3,剩下的三個數為1即可。

 

#include<bits/stdc++.h>
using namespace std;
int t,n;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>n;
        cout<<n-3<<' '<<1<<' '<<1<<' '<<1<<'\n';
    }
    return 0;
}

B. Array Cloning Technique

You are given an array aa of nn integers. Initially there is only one copy of the given array.

You can do operations of two types:

  1. Choose any array and clone it. After that there is one more copy of the chosen array.
  2. Swap two elements from any two copies (maybe in the same copy) on any positions.

You need to find the minimal number of operations needed to obtain a copy where all elements are equal.

Input

The input consists of multiple test cases. The first line contains a single integer tt (1t1041≤t≤104) — the number of test cases. Description of the test cases follows.

The first line of each test case contains a single integer nn (1n1051≤n≤105) — the length of the array aa.

The second line of each test case contains nn integers a1,a2,,ana1,a2,…,an (109ai109−109≤ai≤109) — the elements of the array aa.

It is guaranteed that the sum of nn over all test cases does not exceed 105105.

Output

For each test case output a single integer — the minimal number of operations needed to create at least one copy where all elements are equal.

題目大意:給定一個排列,每次可以進行如下操作:1.複製該排列為一個新的排列。2.將原排列中的任意一個數與複製後的排列中任意一個數互換。

求最少經過幾次操做可以實現原排列各個位置的值相同。

思路:每次複製後,取原排列中重複次數最多的數乘2到符合題意為止。

#include<bits/stdc++.h>
using namespace std;
int t,n;
int a[100001];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>n;
        int maxn=0;
        map<int,int>mp;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            mp[a[i]]++;
            maxn=max(maxn,mp[a[i]]);
        }
        if(maxn==n){
            cout<<'0'<<'\n';
            continue;
        }
        int ans=1;
        n-=maxn;
        if(n-maxn>=0)
            ans+=maxn;
        else
            ans+=n;
        n-=maxn;
        while(n>0)
        {
            ans++;
            maxn*=2;
            if(n-maxn>=0)
                ans+=maxn;
            else 
                ans+=n;
            n-=maxn;
        }
        cout<<ans<<'\n';
    }
    return 0;
}

 

C. Tree Infection 

A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. The parent of a vertex vv (different from root) is the previous to vv vertex on the shortest path from the root to the vertex vv. Children of the vertex vv are all vertices for which vv is the parent.

You are given a rooted tree with nn vertices. The vertex 11 is the root. Initially, all vertices are healthy.

Each second you do two operations, the spreading operation and, after that, the injection operation:

  1. Spreading: for each vertex vv, if at least one child of vv is infected, you can spread the disease by infecting at most one other child of vv of your choice.
  2. Injection: you can choose any healthy vertex and infect it.

This process repeats each second until the whole tree is infected. You need to find the minimal number of seconds needed to infect the whole tree.

Input

The input consists of multiple test cases. The first line contains a single integer tt (1t1041≤t≤104) — the number of test cases. Description of the test cases follows.

The first line of each test case contains a single integer nn (2n21052≤n≤2⋅105) — the number of the vertices in the given tree.

The second line of each test case contains n1n−1 integers p2,p3,,pnp2,p3,…,pn (1pin1≤pi≤n), where pipi is the ancestor of the ii-th vertex in the tree.

It is guaranteed that the given graph is a tree.

It is guaranteed that the sum of nn over all test cases doesn't exceed 21052⋅105.

Output

For each test case you should output a single integer — the minimal number of seconds needed to infect the whole tree.

題目大意:給定一棵樹,每一秒可以感染一個節點,同時具有相同父親節點的節點中如果存在已經被感染的節點的話,這幾個節點中會有一個節點收到傳播。

思路:每一部分具有相同父親節點的節點都要花費一秒去感染,而對於每一堆有一個受到感染的節點來說其他節點全部感染所需要的最小時間是節點的子節點數 - 傳播次序 + 1,知道這些後模擬一邊即可

#include<bits/stdc++.h>
using namespace std;
int t,n;
int a[200002];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>n;
        memset(a,0,sizeof(a));
        int ans=1;
        for(int i=1;i<n;i++)
        {
            int k;
            cin>>k;
            a[k]++;
        }
        sort(a+1,a+1+n,cmp);
        priority_queue<int,vector<int>,less<int>>q;
        for(int i=1;i<=n;i++)
        {
            if(a[i]==0)
                break;
            ans++;
            q.push(a[i]-1+i);
        }
        while(ans<q.top())
        {
            int k=q.top()-1;
            ans++;
            q.pop();
            q.push(k);
        }
        cout<<ans<<'\n';
    }
    return 0;
}