3 personal training summary

Posted by FredAt on Fri, 31 Dec 2021 14:14:47 +0100

Red wine competition Title A: Title Link: Click here to transfer


Meaning:
Given n non decreasing numbers, you are required to change a bit of a number so that it does not form a non decreasing sequence. If Impossible cannot be output
Idea:
For simulation, enumerating two adjacent numbers is still legal if the first bit of the previous number becomes 9 or the first bit of the next number becomes 1 (the single digit becomes 0). Continue enumerating until all numbers are traversed.

#include<bits/stdc++.h>
using namespace std;
#define MAXN 105
#define ll long long
int n;
ll a[MAXN];
string s[MAXN];
ll len[MAXN];
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		s[i] = to_string(a[i]);
		len[i] = (long long)to_string(a[i]).length();
	}
	int f = 0;
	for (int i = 1; i < n; i++)
	{
		if (f == 1) break;
		if (len[i] < len[i + 1]) continue;
		char temp = s[i][0];
		s[i][0] = '9';
		if (s[i] > s[i + 1])
		{
			f = 1;
			continue;
		}
		s[i][0] = temp;//If you can't, change it back
		temp = s[i + 1][0];
		if (len[i + 1] == 1) s[i + 1] = "0";
		else s[i + 1][0] = '1';
		if (s[i] > s[i + 1])
		{
			f = 1;
			continue;
		}
		s[i + 1][0] = temp;//If you can't, change it back
	}
	if(f==0)
	cout << "impossible";
	else
	{
		for (int i = 1; i <= n; i++) cout << s[i] << " ";
	}
	return 0;
}

Link to Title L of red wine competition: Click here to transfer


This question is meaningless. I won't talk about it

#include<bits/stdc++.h>
using namespace std;
string s1, s2;

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> s1 >> s2;
	int ans1 = 0;
	int ans2 = 0;
	int ans = 0;
	for (int i = 0; i < s1.length(); i++) if (s1[i] == '(') ans1++;
	for (int i = 0; i < s2.length(); i++) if (s2[i] == '(') ans2++;
	ans = ans1 * ans2;
	if (ans == 0)
	{
		cout << 0;
		return 0;
	}
	for (int i = 1; i <= ans; i++) cout << "S(";
	cout << "0";
	for (int i = 1; i <= ans; i++) cout << ")";
	return 0;
}

Example of Luogu P2574 line segment tree: Click here to transfer


Meaning:
Algorithm problem, or Chinese, no translation, really cool
Idea:
Each time you flip, the number of 1 is equal to the number of 0 in the previous round. This is the content of the push up.
The number of flips 1 for odd times changes, and the number of flips 1 for even times does not change. This is the content of pushdown

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
struct segtreenode
{
	int l, r, len;
	int val, lazy;
}tree[MAXN*4];
int a[MAXN];
string s;
int n,m;
void pushup(int rt) { tree[rt].val = tree[rt * 2].val + tree[rt * 2 + 1].val; }
void build(int rt,int l,int r)
{
	tree[rt].l = l; tree[rt].r = r; tree[rt].len = r - l + 1;
	if (l == r)
	{
		tree[rt].val = a[l];
		return;
	}
	int mid = (l + r) / 2;
	if (mid >= l) build(rt * 2, l, mid);
	if (mid < r) build(rt * 2 + 1, mid + 1, r);
	pushup(rt);
}
void pushdown(int rt)
{
	if (tree[rt].lazy%2==1)
	{
		tree[rt * 2 + 1].lazy += tree[rt].lazy;
		tree[rt * 2].lazy += tree[rt].lazy;
		tree[rt * 2].val = tree[rt * 2].len - tree[rt * 2].val;
		tree[rt * 2 + 1].val = tree[rt * 2 + 1].len - tree[rt * 2 + 1].val;
		tree[rt].lazy = 0;
	}
	else if (tree[rt].lazy % 2 == 0)
	{
		tree[rt * 2 + 1].lazy += tree[rt].lazy;
		tree[rt * 2].lazy += tree[rt].lazy;
		tree[rt].lazy = 0;
	}
}
void update(int rt, int l, int r)
{
	if (tree[rt].l > r || tree[rt].r < l) return;
	if (tree[rt].l >= l && tree[rt].r <= r)
	{
		tree[rt].lazy += 1;
		tree[rt].val = tree[rt].len - tree[rt].val;
		return;
	}
	pushdown(rt);
	update(rt * 2, l, r);
	update(rt * 2 + 1, l, r);
	pushup(rt);
}
int query(int rt, int l, int r)
{
	if (tree[rt].l > r || tree[rt].r < l) return 0;
	if (tree[rt].l >= l && tree[rt].r <= r) return tree[rt].val;
	pushdown(rt);
	return query(rt * 2, l, r) + query(rt * 2 + 1, l, r);
}
int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m >> s;
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] == '0') a[i + 1] = 0;
		if (s[i] == '1') a[i + 1] = 1;
	}
	build(1, 1, n);
	while (m--)
	{
		int f,l,r;
		cin >> f;
		cin >> l >> r;
		if (f == 0)
		{
			update(1, l, r);
		}
		else if (f == 1)
		{
			cout << query(1, l, r) << endl;
		}
	}
	return 0;
}

Codeforces 1549A title link: Click here to transfer


Meaning:
Given a prime number, you are required to construct two numbers so that the prime number is the same as the modulus of the two numbers
Idea:
The prime number must be odd, then one is 2, one is n-1, and the module must be 1

#include<bits/stdc++.h>
using namespace std;
int t,n;
map <int,int> mp;

int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>n;
        cout<<2<<" "<<n-1<<endl;
    }


    return 0;
}

Codeforces 1549B title link: Click here to transfer


Meaning:
There are n pieces in total. They should go to the end as many as possible. If there are no enemy pieces in front of them, they can only move forward; If so, they can only go to the front left or right. Ask how many pieces can finally reach the end.
Idea:
I don't know what the meaning of this problem is. Just simulate it according to his meaning, without any amount of thinking.

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
string s1,s2;
int t,n;
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>t;
    while(t--)
    {
        cin>>n;
        cin>>s1>>s2;
        int ans=0;
        for(int i=0;i<s1.length();i++)
        {
            if(s1[i]=='1')
            {
                if(i-1>=0&&s2[i-1]=='1')
                {
                    s2[i-1]='0';
                    ans++;
                   // cout<<s1<<" "<<s2<<endl;
                    continue;
                }
                if(i+1<n&&s2[i+1]=='1')
                {
                    s2[i+1]='0';
                    ans++;
                   // cout<<s1<<" "<<s2<<endl;
                    continue;
                }
            }
            else
            {
                if(s2[i]=='1')
                {
                    s2[i]='0';
                    ans++;
                   // cout<<s1<<" "<<s2<<endl;
                    continue;
                }
            }
            //cout<<s1<<" "<<s2<<endl;
        }
        cout<<ans<<endl;
    }

    return 0;
}

Codeforces 1549C title link: Click here to transfer


Meaning:
You have to maintain a circle of friends. The person with the weakest ability in a circle of friends will commit suicide, and suicide will continue. You can add friends to someone or delete a friendship. For each query, you need to output the number of people still alive on the field. A person's ability value is his number.
Idea:
Really stupid question, a pile of things didn't make it clear. First of all, people will come back to life after every query. So this question is independent of each query? Fart, every addition and deletion operation before has an impact on the back. The person who worked out this problem is really cerebral palsy
Conclusion 1: after a round of inquiry, there will be no friends on the field (everyone's number is unique)
Conclusion 2: after a round of inquiry, only the strongest one in their circle of friends can survive.
So we maintain a statistical array, which counts how many are higher in the i-th person's circle of friends. Only when cnt[i] is 0 can we finally survive.

#include<bits/stdc++.h>
using namespace std;
int t, m, n,k;
#define MAXN 200005
int cnt[MAXN];
int ans;//Dead man
void solve(int l,int r)
{
	if (l > r)
	{
		cnt[r]++;
		if (cnt[r] == 1) ans++;
	}
	else if (l < r)
	{
		cnt[l]++;
		if (cnt[l] == 1) ans++;
	}
}
int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		int l, r;
		cin >> l >> r;
		solve(l, r);
	}
	cin >> k;
	while (k--)
	{
		int f;
		cin >> f;
		if (f == 1)//Edging
		{
			int l, r;
			cin >> l >> r;
			solve(l, r);
		}
		else if (f == 2)//Edge reduction
		{
			int l, r;
			cin >> l >> r;
			if (l > r)
			{
				cnt[r]--;
				if (cnt[r] == 0) ans--;
			}
			else if (l < r)
			{
				cnt[l]--;
				if (cnt[l] == 0) ans--;
			}
		}
		else cout << n - ans << endl;
	}

	return 0;
}

Codeforces 1549D title link: Click here to transfer


Meaning:
Find a continuous interval so that they modulo a number and get the same remainder. Find the maximum length of this interval.
Idea:
It is still a line segment tree + ruler. This is ridiculous. It's a lot of strange things.
A new sequence is constructed by the difference between two adjacent elements. The problem becomes the maximum interval length of any two numbers gcd greater than 1 in all intervals. The gcd of the interval is maintained by the line segment tree, and the length of the interval is determined by first determining the right end point and then moving the left end point to the right.

#include<bits/stdc++.h>
using namespace std;
#define MAXN 200005
#define ll long long
int t, n;
ll ans;
ll a[MAXN];//Difference between two adjacent elements
ll gcd(ll x, ll y)
{
	if (x < y) swap(x, y);
	while (y)
	{
		ll temp = x % y;
		x = y;
		y = temp;
	}
	return x;
}
struct segtreenode
{
	int l, r;
	ll val;//gcd
}tree[MAXN * 4];
void pushup(int rt) { tree[rt].val = gcd(tree[rt * 2].val, tree[rt * 2 + 1].val); }
void build(int rt, int l, int r)
{
	tree[rt].l = l;
	tree[rt].r = r;
	if (l == r)
	{
		tree[rt].val = a[l];
		return;
	}
	int mid = (l + r) / 2;
	if (mid >= l) build(rt * 2, l, mid);
	if (mid < r) build(rt * 2 + 1, mid + 1, r);
	pushup(rt);
}
ll query(int rt, int l, int r)
{
	if (tree[rt].l > r || tree[rt].r < l) return 0;//
	if (tree[rt].l >= l && tree[rt].r <= r) return tree[rt].val;
	return gcd(query(rt * 2, l, r), query(rt * 2 + 1, l, r));
}
int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> t;
	while (t--)
	{
		ans = 1;
		cin >> n;
		for (int i = 1; i <= n; i++)
		{
			cin >> a[i];
			a[i - 1] = abs(a[i] - a[i - 1]);
		}
		if (n == 1)
		{
			cout << 1 << endl;
			continue;
		}
		build(1, 1, n);
		ll j = 1;
		for (ll i = 1; i <= n - 1; i++)
		{
			while (j <= i && query(1, j, i) == 1) j++;//Ruler method
			ans = max(ans, i - j + 2);
		}

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

Topics: C++ Algorithm greedy algorithm ICPC