Codeforces Round #735 (Div. 2)

Posted by telsiin on Mon, 03 Jan 2022 03:37:24 +0100

This div2 mainly focuses on the derivation of the formula and the optimization of time complexity. This requires us to be sensitive to some digital patterns in life.

The topic gives us a lot of hints, such as the amount of data in 1e5. If we adopt the method of pairing one by one, the time complexity will timeout. Considering the nesting of various data structures, there is no suitable method. At this time, our thinking direction should be biased towards law and simplification. We might as well enumerate the data to find the rules.


General idea of the topic
A number consisting of N numbers is given (the range of n is (2,1e5)). The size of each number is between (1,1e6). Ask the maximum value of the product of the maximum value and the minimum value of the set composed of all numbers in any interval greater than 2

Problem solving ideas
This is a very classic law summary question. Starting from the most ordinary, we will find that the time complexity of finding the values of all intervals is O(1e10). First, I consider the derivation of dp dynamic programming. Then all intervals are required to be maintained with (l,r). Obviously, the time complexity is not optimized. At this time, we might as well think about this problem greedily. Whether we can enumerate from the largest place, the answer is No. Finally, under the test of various methods, there is no consistent solution. Then, starting from the law, we will find that for three numbers, we will find that f(1,3) is always less than max(f(1,2),f(2,3)). We will find that when the array is merged, the size of the minimum value will never increase.

code

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

#define debug(a) cout << #a << ": " << a << endl;
#define LL long long 
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const int maxn = 1e5+10;
int a[maxn];

void solve()
{
    int n;
    cin >> n;
    for(int i = 1;i <= n;++i) {
        cin >> a[i];
    }
    LL ans = 0;
    for(int i = 2;i <= n;++i) {
        ans = max(ans,a[i]*1ll*a[i-1]);
    }
    cout << ans << endl;
}

int main()
{
    IO;
    int t;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

Topic summary
This is a very common rule summary question. Similar to the short board effect, in order to establish an enduring knowledge system, we must constantly learn and consolidate what we have learned. Instead of leaving loopholes in all aspects, more learning is better than intensive learning.


General idea of the topic
Given an array of length N and an integer K. Find any number pair (i,j) i= j satisfies ij-k(ai*aj) to obtain the maximum value. Range of n (2,1e5), range of K min (n,100), range of ai (1, n)

Problem solving ideas
If we want to get the maximum value, we might as well take i=n-1,j=n; We can find that the minimum value of f(n-1,n) is n^2-2kn-n, and the maximum value of f(i,n) is in. To make f(i,n) greater than f(n-1,n), the range of i needs to be greater than n-2k. Thus, the time complexity can be simplified to O(1e7)

code

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

#define debug(a) cout << #a << ": " << a << endl;
#define LL long long 
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const int maxn = 1e5+10;
int a[maxn];


void solve()
{
    int n,k;
	cin >> n >> k;
	for(int i = 1;i <= n;++i) {
		cin >> a[i];
	}
	int l = max(1,n-200);
	LL ans = -1*1e18;
	for(int i = l;i < n;++i) {
		for(int j = i+1;j <= n;++j) {
			ans = max(ans,i*1ll*j-1ll*k*(a[i] | a[j]));
		}
	}
	cout << ans << endl;
}

int main()
{
    IO;
    int t;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

Topic summary
A classic rule summary question, which is not very difficult and tests your thinking. But it also gives relevant tips.

General idea of the topic
There are t groups of samples, and the range of T (1,3e4)
Each group of examples is given two numbers N and m, and their range is (1,1e9)
From n XOR 0,n XOR 1, ·······, n XOR m.
Find the value of the smallest natural number that does not appear in the first array composed of these numbers.

Problem solving ideas
We might as well think from another angle that a XOR b equals c. Then a XOR c is equal to b. From this point of view, we can find that if the XOR value of a is less than b. Then a can get that value through XOR. The problem is to find the minimum value so that the value of a and its XOR is greater than or equal to m+1

code

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

#define debug(a) cout << #a << ": " << a << endl;
#define LL long long 
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

void solve()
{
    int n,m;
    cin >> n >> m;
    ++m;
    int ans = 0;
    for(int k = 30;k >= 0;k--) {
        if((n>>k&1) == (m>>k&1)) continue;
        else if((n>>k&1) == 1) break;
        else ans |= (1<<k);
    }
    cout << ans << endl;
}

int main()
{
    IO;
    int t;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

Topic summary
XOR, we might as well first consider the binary representation of all numbers.

General idea of the topic
Construct a string so that each substring in the string appears an odd number of times.

Problem solving ideas
In order to make the number of occurrences of each substring odd, we use as few strings as possible. The feasibility of the method is proved by experiments. See the code.

code

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

#define debug(a) cout << #a << ": " << a << endl;
#define LL long long 
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

int main()
{
    IO;
    int t;
    cin >> t;
    while(t--){
         int n;
         cin >> n;
         if(n == 1) {
            cout << 'a';
         }
         else if(n%2 == 0) {
            for(int i = 0;i < n/2;++i) cout << 'a';
            cout << 'b';
            for(int i = 0;i < n/2-1;++i) cout << 'a';
         }
         else {
            for(int i = 0;i <= n/2-1;++i) cout << 'a';
            cout << 'b' << 'c';
            for(int i = 0;i < n/2-1;++i) cout << 'a';
         }
         cout << endl;
    }
    return 0;
}

Topic summary
String construction: first, try to use a small number of strings; Second, large-scale data construction experience.

Topic summary
An abstract pruning to optimize the time complexity.

code

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

#define debug(a) cout << #a << ": " << a << endl;
#define LL long long 
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
const int maxn = 1e5+10,mod = 998244353;
int ans[maxn];
vector<vector<int>> ej(maxn);
int eo[maxn];
int sz[maxn];

void dfs(int p, int i) {
	int o;
	sz[i] = 1;
	for (o = eo[i]; o--; ) {
		int j = ej[i][o];
		if (j != p) {
			dfs(i, j);
			sz[i] += sz[j];
		}
	}
}

void solve()
{
    int n;
    cin >> n;
    for(int i = 0;i < n;++i) eo[i] = 0;
    for(int i = 0;i < n-1;++i) {
        int x,y;
        cin >> x >> y;
        x--,y--;
        eo[x]++;
        ej[x].push_back(y);
        eo[y]++;
        ej[y].push_back(x);
    }
    for(int i = 0;i <= n+5;++i) ans[i] = 0;
    ans[1] = 1;
    for(int i = 0;i < n-1;++i) 
        ans[1] = ans[1]*2%mod;
    dfs(-1,0);
    for (int i = 2;i <= n;i++)
    if ((sz[0] - 1) % i == 0) {
        int good = 1;
        for (int j = 1;j < n;j++)
            if (sz[j] % i > 1) {
                good = 0;
                break;
            }
        if (good)
            ans[i]++;
    }
    for (int i = n;i >= 1;i--)
        for (int j = i + i;j <= n;j += i)
            ans[i] = (ans[i] - ans[j] + mod) % mod;
    for (int i = 1; i <= n; i++)
        cout << ans[i] << ' ';
    cout << endl;
    for(int i = 0;i < n+5;++i) {
        ej[i].clear();
    }
    return ;
}

int main()
{
    IO;
    int t;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

Topics: string cf