Codeforces Round #774 (Div. 2)题解
Posted 桂月二四
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #774 (Div. 2)题解相关的知识,希望对你有一定的参考价值。
A.Square Counting
链接
Luis has a sequence of 𝑛+1 integers 𝑎1,𝑎2,…,𝑎𝑛+1. For each 𝑖=1,2,…,𝑛+1 it is guaranteed that 0≤𝑎𝑖<𝑛, or 𝑎𝑖=𝑛2. He has calculated the sum of all the elements of the sequence, and called this value 𝑠.
Luis has lost his sequence, but he remembers the values of 𝑛 and 𝑠. Can you find the number of elements in the sequence that are equal to 𝑛2?
We can show that the answer is unique under the given constraints.
题意:有一个n+1长度的数组a 0<=ai<=n-1 或 ai=n^2 ,现在知道n的大小和数字元素的和s,问有几个ai=n ^2
题解:注意到(n-1)(n+1)<nn , 也就是说。不等于n^2的ai的和小于 n ^2,所以答案是 s/(n*n)
B.Quality vs Quantity
比较简单
C.Factorials and Powers of Two
A number is called powerful if it is a power of two or a factorial. In other words, the number 𝑚 is powerful if there exists a non-negative integer 𝑑 such that 𝑚=2𝑑 or 𝑚=𝑑!, where 𝑑!=1⋅2⋅…⋅𝑑 (in particular, 0!=1). For example 1, 4, and 6 are powerful numbers, because 1=1!, 4=22, and 6=3! but 7, 10, or 18 are not.
You are given a positive integer 𝑛. Find the minimum number 𝑘 such that 𝑛 can be represented as the sum of 𝑘 distinct powerful numbers, or say that there is no such 𝑘.
题意:给定一个整数n,使用最少的不重复的2次幂或者阶乘数,使得这些数相加等于n。
注意到,这题一定有解,不难得出一个答案是n的二进制上1的位数,但是还有阶乘的存在;
又注意到,<=1e12的阶乘数仅有十五个,因此可以暴力枚举使用哪些阶乘数,然后再对剩下的数计算二进制上1的位数。
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
#define pb push_back
#define debug(x) cerr<<#x<<'='<<x<<'\\n'
#define debugg(x,y) cerr<<#x<<'='<<x<<','<<#y<<'='<<y<<'\\n'
#define FOR(a,b,c) for(int a=(b),a##_end=(c);a<=a##_end;++a)
#define ROF(a,b,c) for(int a=(b),a##_end=(c);a>=a##_end;--a)
#define FASTIO() cin.sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define rvs(s) reverse(s.begin(),s.end())
#define all(s) s.begin(),s.end()
#define sz(s) (int)(s.size())
#define int long long
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 200010 ,M = 1000010,mod = 998244353;const double eps = 1e-9;
ll qmi(ll,ll);
template<typename T>inline bool chkmin(T &x,const T &y)return y<x?x=y,1:0;
template<typename T>inline bool chkmax(T &x,const T &y)return x<y?x=y,1:0;
template <typename T> void inline read(T &x)
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') if (s == '-') f = -1; s = getchar();
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
ll n,m,k;
signed main()
vector<ll> v;
ll now = 6;
for(ll i=4;;i++)
v.pb(now);
now*=i;
if(now>1e12) break;
int d = v.size();
int T;
read(T);
while(T--)
read(n);
int ans = 2e9;
for(int i=0;i<(1<<d);i++)
ll sum = 0,cnt = 0;
for(int j=0;j<d;j++)
if(i>>j&1)
sum+=v[j],++cnt;
if(sum>n) continue;
ll t = n-sum;
for(int j = __lg(t);j>=0;j--)
cnt+=t>>j&1;
ans = min(ans,cnt);
cout<<ans<<'\\n';
return 0;
ll qmi(ll a,ll b) ll res=1;a%=mod; for(;b;b>>=1)if(b&1)res=res*a%mod;a=a*a%mod;return res;
D.Weight the Tree
You are given a tree of 𝑛 vertices numbered from 1 to 𝑛. A tree is a connected undirected graph without cycles.
For each 𝑖=1,2,…,𝑛, let 𝑤𝑖 be the weight of the 𝑖-th vertex. A vertex is called good if its weight is equal to the sum of the weights of all its neighbors.
Initially, the weights of all nodes are unassigned. Assign positive integer weights to each vertex of the tree, such that the number of good vertices in the tree is maximized. If there are multiple ways to do it, you have to find one that minimizes the sum of weights of all vertices in the tree.
题意:给定一个节点为n的树。当一个结点的权值等于周围结点的权值时,这个结点是good。权值由我们自己决定,求最多的good结点,若有多组答案,输出权值和最小的那个。
题解:当n==2时,两个结点都为good结点,权值都为1
当n>2时,一条边的两个结点不可能同时为good结点,于是就可以dp。我们可以让good结点等于他的度,不是good的结点权值为1,这样就能保证权值和最小。
定义数组PII f[i][2] 其中f[i][1]代表当根结点为i时且该结点为good结点,在子树中能形成的最多good结点及其最小权值。 同理f[i][1] 代表i不是good结点…
有上面的分析可知f[u][1] 只能从f[j][0]转移而来,f[u][0]可以从f[j][1]和f[j][0]中的较大者转移而来。
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
#define pb push_back
#define debug(x) cerr<<#x<<'='<<x<<'\\n'
#define debugg(x,y) cerr<<#x<<'='<<x<<','<<#y<<'='<<y<<'\\n'
#define FOR(a,b,c) for(int a=(b),a##_end=(c);a<=a##_end;++a)
#define ROF(a,b,c) for(int a=(b),a##_end=(c);a>=a##_end;--a)
#define FASTIO() cin.sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define rvs(s) reverse(s.begin(),s.end())
#define all(s) s.begin(),s.end()
#define sz(s) (int)(s.size())
#define int long long
using namespace std;
typedef long long ll;
const int N = 200010 ,M = 1000010,mod = 998244353;const double eps = 1e-9;
template<typename T>inline bool chkmin(T &x,const T &y)return y<x?x=y,1:0;
template<typename T>inline bool chkmax(T &x,const T &y)return x<y?x=y,1:0;
template <typename T> void inline read(T &x)
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') if (s == '-') f = -1; s = getchar();
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
int n,m,k;
int h[N],e[M],ne[M],idx,d[N];
struct node
int first,second;
bool operator < (const node &W) const
if(first!=W.first)
return first<W.first;
return second>W.second;
bool operator > (const node &W) const
if(first!=W.first)
return first>W.first;
return second<W.second;
bool operator == (const node &W) const
if(first==W.first&&second==W.second)
return 1;
return 0;
;
void add(int a, int b)
e[idx] = b,ne[idx] = h[a], h[a] = idx ++ ;
node f[N][2];
void dfs(int u,int fa)
f[u][1] = 1,d[u],f[u][0] = 0,1;
for(int i = h[u];~i;i = ne[i])
int j = e[i];
if(j==fa) continue;
dfs(j,u);
f[u][1].first+=f[j][0].first;
f[u][1].second+=f[j][0].second;
node t = max(f[j][0],f[j][1]);
f[u][0].first+=t.first;
f[u][0].second+=t.second;
int a[N];
void build(int u,int ans,int fa)
if(ans==1)
a[u] = d[u];
for(int i = h[u];~i;i = ne[i])
int j = e[i];
if(j==fa) continue;
build(j,0,u);
else
a[u] = 1;
for(int i = h[u];~i;i = ne[i])
int j = e[i];
if(j==fa) continue;
if(f[j][0]>f[j][1])
build(j,0,u);
else build(j,1,u);
signed main()
memset(h,-1,sizeof h);
read(n);
if(n==2)
puts("2 2\\n 1 1");
return 0;
for(int i=1;i<n;i++)
int a,b;
read(a),read(b);
add(a,b),add(b,a);
d[a]++,d[b]++;
dfs(1,-1);
node ans = max(f[1][0],f[1][1]);
// cout<<f[1][0].first<<' '<<f[1][0].second<<endl;
// cout<<f[1][1].first<<' '<<f[1][1].second<<endl;
cout<<ans.first<<' '<<ans.second<<endl;
if(f[1][0]>f[1][1])
build(1,0,-1);
else build(1,1,-1);
for(int i=1;i<=n;i++)
cout<<a[i]<<' ';
return 0;
以上是关于Codeforces Round #774 (Div. 2)题解的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #774 (Div. 2)(ABCDE)
Codeforces Round #774 (Div. 2)题解
Codeforces Round #774 (Div. 2)题解
Codeforces Round #436 E. Fire(背包dp+输出路径)