https://ac.nowcoder.com/acm/contest/4784/B
B.阶乘
题意:给出一个正整数p 要你求一个最小的正整数n 使得 n的阶乘 为 p 的倍数
思路:先要知道 n的阶乘要为p的倍数 则等价于 n的阶乘中包含所有p的素因子个数 如果n的阶乘都包含了 大于n的阶乘就更不用说了 所以我们先对p进行质因数分解 然后遍历所有因子判断是否符合条件 二分即可
tip:用cin 加 long long 会T
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
int vis[N];
bool check(int x,int y)
{
int cnt = 0;
while(x)///计算该数中包含该因子的个数
{
cnt += x / y;
x /= y;
}
return cnt >= vis[y];///大于等于p中该因子个数
}
int main()
{
ios::sync_with_stdio(false);
int t; cin >> t;
while(t --)
{
int p;
memset(vis,0,sizeof(vis));
cin >> p;
int n = p;
for(int i = 2;i*i <= n;i ++)///质因数分解
{
while(p % i == 0)
{
p /= i;
vis[i] ++ ;///对应因子数++
}
}
int ma = p;
for(int i = 2;i * i <= n;i ++)
{
if(n % i == 0 && vis[i])///若为p的因子
{
int l = 0;
int r = 1e9;
int x = 0;
while(l + 1 < r)///二分符合条件的答案
{
int mid = l + r >> 1;
if(check(mid,i))
r = mid,x = mid;
else
l = mid;
}
ma = max(ma,x);///取最大值 是一定要满足条件 即所有因子都要有
}
}
cout << ma << '\n';
}
return 0;
}
E.A+B
输出样例即可 2^32次方
G.
思路:先计算每条边在答案中被加了多少次 dfs一下 然后升序排序 贪心把边权加上即可
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
vector <int> a[N];
int sz[N];
void dfs(int u,int v)
{
sz[u] = 1;
for(auto it : a[u])
{
if(it == v)
continue;
dfs(it,u);
sz[u] += sz[it];
}
}
int main()
{
int n;
cin >> n;
for(int i = 1;i < n;i ++)
{
int u , v;
cin >> u >> v;
a[u].push_back(v);
a[v].push_back(u);
}
dfs(1,1);
for(int i = 1;i <= n;i ++)
sz[i] = min(sz[i],n - sz[i]);
sort(sz + 1,sz + 1 + n);
LL sum = 1;
LL res = 0;
for(int i = n;i >= 2;i --)
res += 1LL * sz[i] * (sum ++) * (n - sz[i]);
cout << res << '\n';
return 0;
}
H.
题意:给你n个数 能不能构成 2^30 次方
思路:只要和大于2^30次方 就一定可以 降序排序后贪心即可
证明懒得写了 嫖一嫖
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define fi first
#define se second
const int N = 100004;
typedef pair <LL,LL> PLL;
PLL a[N];
LL vis[N];
int main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while(t --)
{
int m;
cin >> m;
LL sum = 0;
for(int i = 1;i <= m;i ++)
{
int x;
cin >> x;
a[i].fi = 1 << x;
a[i].se = i;
sum += a[i].fi;
}
if(sum < (1<<30))
{
cout << "impossible" << '\n';
continue;
}
sort(a + 1,a + 1 + m,greater<PLL>());
for(int i = 1;i <= m;i ++)
vis[i] = 0;
sum = 1 << 30;
for(int i = 1;i <= m;i ++)
{
if(a[i].fi <= sum)
{
sum -= a[i].fi;
vis[a[i].se] = 1;
}
}
for(int i = 1;i <= m;i ++)
cout << vis[i];
cout << '\n';
}
return 0;
}