n^2log动态规划
新生赛题
F. tree options
如果能想到弱化版操作为每个节点值都小于等于0,就很容易想到n方log的做法。
但是回到原题会发现单调性有变化,不能直接二分。由于奇数轮数和偶数轮数分别有自己的单调性,就可以对奇偶轮数分别二分然后枚举非整轮部分。dp算每个点还要多少次能变为合法点。
题解有复杂度优化待学。
代码在好几个地方写挂了
1.ans大小
2.对奇数偶数轮数二分的方法
3.不知道为什么函数传值比开数组快了1s。。
#include <bits/stdc++.h> using namespace std; #define lowbit(x) (x & (-x)) #define pii pair<int, int> #define mkp make_pair #define LL long long #define ll long long #define endl '\n' const int N = 2e3 + 10, inf = 1e9; LL n, rt, f[N], a[N], p, nw; vector<int>E[N]; void dfs(int x, int fa) { f[x] = a[x]; LL tmp = nw + (x <= p); for (int i:E[x]){ if(i == fa) continue; dfs(i, x); f[x] += f[i]; } f[x] = (f[x]-tmp > 0) ?(f[x] - tmp) : (f[x] - tmp & 1); // if(p == 0)cout << f[x] << ' '<< x << 'x' << tmp << endl; } void solve() { cin >> n >> rt; for(int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; E[u].push_back(v); E[v].push_back(u); } if (n == 1) { cout << a[1] << endl; return; } LL ans = 1ll*inf*N; for(int i = 0; i < n; i++) { p = i; LL l = 0, r = inf, mid = (l+r)/2; while(l < r) { nw = mid*2+1; dfs(rt, 0); if(f[rt]) l = mid + 1; else r = mid; mid = (l + r) / 2; } ans = min(ans, (mid * 2 + 1) * n + i); l = 0, r = inf, mid = (l + r) / 2; while(l < r) { nw = mid*2; dfs(rt, 0); if(f[rt]) l = mid + 1; else r = mid; mid = (l + r) / 2; } ans = min(ans, mid*2*n + i); } if(ans == 1ll*inf*N)cout<<-1<<endl; else cout<<ans<<endl; for (int i = 0;i <= n; i++)E[i].clear(); } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); int T = 1; cin >> T; while (T--) solve(); } /* 1 3 2 2 1 3 2 1 3 2 */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话