Codeforces Round 891 (Div. 3)
E
题意:
给你一个数组a = [n
个区间([min(
然后定义函数f(x)(x
思路:
首先要明白对于个
所以
void solve()
{
int n; cin >> n;
std::vector<pair<LL, LL>> a(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> a[i].first;
a[i].second = i;
}
sort(a.begin(), a.end());
vector<LL> s(n + 1);
for (int i = 1; i <= n; i++) s[i] = s[i - 1] + a[i].first;
std::vector<LL> ans(n + 1);
for (int i = 1; i <= n; i++)
{
ans[a[i].second] = i * a[i].first - s[i] + (s[n] - s[i]) - (n - i) * a[i].first + n;
}
for (int i = 1; i <= n; i++)
cout << ans[i] << ' ';
cout << endl;
}
F
题意:
已知数组a, 寻找满足
思路:
因为
所以 直接解方程就行
inline void solve(){
int n, q; cin >> n;
map<LL,int>mp;
for(int i = 1; i <= n; i++){
int x; cin >> x;
mp[x] ++;
}
cin >> q;
while (q--)
{
LL x, y;
cin >> x >> y;
if (x * x - 4 * y < 0) {
cout << 0 << " ";
continue;
}
LL s = sqrt(x * x - 4 * y);
LL a = (x + s) / 2;
LL b = (x - s) / 2;
if (a + b != x || a * b != y) {
cout << 0 << " ";
continue;
}
if (a == b) {
int c = mp[a];
cout << 1LL * c * (c - 1) / 2 << " ";
} else {
cout << 1LL * mp[a] * mp[b] << " ";
}
}
cout << '\n';
}
G
题意:
给你一棵树,你可以在树上加边,问有多少种加法使得加边后的图的最小生成树依然是给出的那棵树,新图的边权不能大于S
思路:
我们参照Kruskal算法重构图,Kruskal每次都贪心的选离集合最近的那一条边,这启发我们如果想在边(u, v, w)上加一条边,那么这条边的大小一定是属于[w + 1, s]的,因为如果加的边是小于w的,那么最小生成树在选边的时候会选小的那条从而导致生成树发生改变,因为生成树的每一条边都已知,所以对于每一条边而言贡献值为
size[u] * size[v] - 1为点的选择情况,要除开(a, b)这条本身存在的边
inline void solve()
{
int n, s; cin >> n >> s;
vector<tuple<int, int, int>> adj;
for (int i = 1; i < n; i++)
{
int u, v, w; cin >> u >> v >> w;
adj.push_back({u, v, w});
}
sort(adj.begin(), adj.end(), cmp);
DSU dsu(n + 1);
LL ans = 1;
for (auto [u, v, w] : adj)
{
ans = (ans * qmi(s - w + 1, (LL)dsu.size(u) * dsu.size(v) - 1)) % MOD;
dsu.merge(u, v);
}
cout << ans << endl;
}
本文作者:自动机
本文链接:https://www.cnblogs.com/monituihuo/articles/17619286.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步