A. Split the Multiset
考虑看成是n个1,每次最多合并其中k个数,最少多少次能合并为一个数
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
// #define endl "\n"
#define pb push_back
#define pii pair<ll, ll>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=1e9 + 7;
const int N = 1e6 + 10;
int n, k, cnt;
void solve()
{
cin >> n >> k;
cnt = 0;
if(n == 1) cout << 0 << endl;
else
{
int cnt = 0;
while(n > 1)
{
cnt ++ ;
n -= (k - 1);
}
cout << cnt << endl;
}
}
signed main()
{
IOS;
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
B. Make Majority
先合并连续的0,然后看此时1和0哪个多即可
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
// #define endl "\n"
#define pb push_back
#define pii pair<ll, ll>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=1e9 + 7;
const int N = 1e6 + 10;
int n, k, cnt, m;
void solve()
{
cin >> n;
string s;
cin >> s;
s = " " + s;
string t;
t += " ";
rep(i, 1, n)
{
if(s[i] == '1') t += '1';
else
{
t += '0';
while(i + 1 <= n && s[i + 1] == '0') i ++ ;
}
}
m = t.size() - 1;
int c1 = 0, c0 = 0;
rep(i, 1, m) if(t[i] == '1') c1 ++ ; else c0 ++ ;
if(c1 <= c0) cout << "No" << endl;
else cout << "Yes" << endl;
}
signed main()
{
IOS;
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
C. Increasing Sequence with Fixed OR
以为是与运算,且要构造的数组严格递增,那么最后一个位置一定可以放n,为了保证严格单调递增,直接低位枚举n的二进制位即可,假设当前枚举到第i位时n的二进制位为1,那么把n-(1<<i)加入答案即可。
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
// #define endl "\n"
#define pb push_back
#define pii pair<ll, ll>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=1e9 + 7;
const int N = 1e6 + 10;
int n;
void solve()
{
cin >> n;
vector<int>ans;
ans.push_back(n);
if(n - lowbit(n) == 0)
{
cout << 1 << endl << n << endl;
return;
}
rep(i, 0, 60)
{
if(n >> i & 1) ans.push_back(n - (1ll << i));
}
reverse(ans.begin(), ans.end());
cout << ans.size() << endl;
for(auto i : ans) cout << i << " ";
cout << endl;
}
signed main()
{
IOS;
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}
D. The Omnipotent Monster Killer
可以看出在经过一些轮操作之后,整个树上的怪物都会被杀死,由于不能选择相邻的点,那么可以想到,当前轮次没有被杀死的怪物,它的父亲或儿子节点上的怪兽就应该有至少一个被杀死,那么可以看出每次大约会杀死剩下节点数的一半的怪物,那么最多需要log轮次即可杀死所有怪物,log(3e5)大约20轮,因此考虑树形dp,f[i][j]表示i的子树的怪物都被杀死,且i在j轮被杀死时,所造成的最小伤害,那么儿子节点只要和当前枚举的轮次不相等那么都可以选,从中选择最小值暴力转移即可。
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define int long long
#define endl "\n"
#define pb push_back
#define pii pair<ll, ll>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int mod=1e9 + 7;
const int N = 1e6 + 20;
int n;
vector<int>p[N];
int a[N], dp[N][21], f[N][21];
void dfs(int u, int fa)
{
int flag = 0;
for(auto j : p[u])
{
if(j == fa) continue;
dfs(j, u);
flag = 1;
}
if(!flag) rep(i, 1, 20) f[u][i] = dp[u][i];
else
{
rep(x, 1, 20) f[u][x] = dp[u][x];
for(auto j : p[u])
{
if(j == fa) continue;
int cnt = 0;
rep(x, 1, 20)
{
cnt = 1e18;
rep(y, 1, 20)
{
if(x == y) continue;
cnt = min(cnt, f[j][y]);
}
f[u][x] += cnt;
}
}
}
}
void solve()
{
cin >> n;
rep(i, 1, n) p[i].clear();
rep(i, 1, n) cin >> a[i];
rep(i, 1, n)
rep(j, 1, 20)
{
dp[i][j] = a[i] * j;
f[i][j] = 1e18;
}
rep(i, 1, n - 1)
{
int u, v;
cin >> u >> v;
p[u].push_back(v);
p[v].push_back(u);
}
dfs(1, 0);
int ans = 1e18;
rep(i, 1, 20) ans = min(ans, f[1][i]);
cout << ans << endl;
}
signed main()
{
IOS;
int t;
t = 1;
cin >> t;
while(t -- )
{
solve();
}
return 0;
}