2022.4.8
Codeforces Round #781 (Div. 2)
A. GCD vs LCM
啊,太久没接触最小公倍数了脑子抽了相成了最大公倍数,导致搞了很久。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int t;
cin >> t;
while(t--)
{
ll n;
cin >> n;
if(n%4==0)
{
ll x = n / 4;
cout << x << ' ' << x << ' ' << x << ' ' << x << '\n';
}
else
{
n -= 2;
ll x = n / 2;
if(n&1)
{
cout << x << ' ' << x + 1<<' ' ;
}
else
cout << x-1 << ' ' << x+1 << ' ';
cout << "1 1" << '\n';
}
}
return 0;
}
B. Array Cloning Technique
呃呃,如果要把一个数组变成全部一样且操作次数最少的话,肯定得挑相同元素最多的那个,每次复制我们可以使原来元素的个数翻倍,然后再swap过去,花费1+x次,不断重复这个过程直到全部交换完
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int a[N];
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int t;
cin >> t;
while(t--)
{
int n;
map<int, int> mp;
cin >> n;
for (int i = 1; i <= n;i++)
{
cin >> a[i];
mp[a[i]]++;
}
int cnt = 0;
for (int i = 1; i <= n;i++)
{
cnt = max(cnt, mp[a[i]]);
}
int res = n - cnt;
if(res==0)
{
cout << 0 << '\n';
}
else
{
int ans = 0;
while(cnt<n)
{
if(cnt+cnt>n)
{
ans += 1 + n - cnt;
break;
}
ans += (1 + cnt);
cnt += cnt;
}
cout << ans << '\n';
}
}
return 0;
}
C. Tree Infection
贪心题,但是写着写着胡思乱想了,看了题解可以用二分来贪心,首先肯定得先感染儿子最多的,感染其中一个儿子剩下的每次都可以感染一个,二分感染的时间,同时对于每个儿子集合,从大到小排序然后求出能感染儿子的,对于第i个被感染的,剩下的能在mid时间内感染mid-i个,然后还需要加上而外感染的和一开始感染的第一个点。即mid>=cnt+ans
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e9;
vector<int> p[N];
int q[N],cnt;
bool check(int mid)
{
int ans = 0;
for (int i = 1; i <= cnt;i++)
{
if(q[i]-(mid-i)>0)
{
ans += q[i]-(mid-i);
}
}
return mid >= ans + cnt;
}
bool cmp(int a,int b)
{
return a > b;
}
int main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
int n;
cin >> n;
for (int i = 1; i <= n;i++)
{
p[i].clear();
q[i] = 0;
}
for (int i = 2; i <= n;i++)
{
int x;
cin >> x;
p[x].push_back(i);
}
cnt = 1;
for (int i = 1; i <= n;i++)
{
if(p[i].size())
q[++cnt] = p[i].size() - 1;
}
sort(q + 1, q + 1 + cnt, cmp);
int l = 1, r = n;
while(l<r)
{
int mid = l + r >> 1;
if(check(mid))
{
r = mid;
}
else
l = mid + 1;
}
cout << l << '\n';
}
return 0;
}
Codeforces Round #640 (Div. 4)