考虑用动态维护每个联通块的根到最远的叶子的距离,每次连边 a→b 时只要用 b 的答案加上 a 到其联通块根的距离更新贡献即可
求一个点到其联通块的路径长度是带权并查集的经典问题,但路径压缩的时候很容易写错需要注意下
#include<cstdio>#include<iostream>#define RI register int#define CI const int&usingnamespace std;
constint N=1e6+5;
int t,n,a,b,c,fa[N],dep[N],dis[N],len[N];
inlineintgetfa(CI x){
if (x==fa[x]) return x;
int t=getfa(fa[x]);
dep[x]=dep[fa[x]]+len[x];
len[x]+=len[fa[x]];
return fa[x]=t;
}
intmain(){
for (scanf("%d",&t);t;--t)
{
RI i; for (scanf("%d",&n),i=1;i<=n;++i) fa[i]=i,dep[i]=dis[i]=len[i]=0;
for (i=1;i<n;++i)
{
scanf("%d%d%d",&a,&b,&c);
int anc=getfa(a);
dis[anc]=max(dis[anc],dep[a]+1+dis[b]);
fa[b]=a; len[b]=1;
printf("%d%c",dis[c]," \n"[i==n-1]);
}
}
return0;
}
#include<cstdio>#include<iostream>#include<vector>#include<queue>#define RI register int#define CI const int&usingnamespace std;
typedef pair <int,int> pi;
constint N=1e6+5,INF=1e9;
int t,n,m,st,x,y,pos[N<<1],vis[N],dis1[N],dis2[N<<1]; vector <pi> v[N];
intmain(){
for (scanf("%d",&t);t;--t)
{
RI i; scanf("%d%d%d",&n,&m,&st);
for (i=1;i<=n;++i) v[i].clear(),vis[i]=0,dis1[i]=INF;
int idx=0; for (i=1;i<=m;++i)
{
scanf("%d%d",&x,&y);
v[x].push_back(pi(y,idx)); pos[idx++]=y;
v[y].push_back(pi(x,idx)); pos[idx++]=x;
}
for (i=0;i<idx;++i) dis2[i]=INF;
dis1[st]=0; queue <int> q; q.push(st);
while (!q.empty())
{
int now=q.front(); q.pop();
for (auto [to,id]:v[now])
if (to!=1&&dis1[to]>dis1[now]+1) dis1[to]=dis1[now]+1,q.push(to);
}
for (auto [x,id]:v[n]) dis2[id^1]=0,dis2[id]=1,q.push(id);
while (!q.empty())
{
int ne=q.front(),now=pos[ne]; q.pop();
if (++vis[now]>2) continue;
for (auto [to,id]:v[now])
{
if (id==(ne^1)) continue;
if (dis2[id]>dis2[ne]+1)
dis2[id]=dis2[ne]+1,q.push(id);
}
}
int ans=INF; for (auto [x,id]:v[1])
ans=min(ans,dis1[x]+dis2[id^1]);
if (v[n].size()<=1||ans>=INF) puts("Boring Game");
elseprintf("Vegetable fallleaves\n%d\n",ans);
}
return0;
}
#include<cstdio>#include<iostream>#include<cmath>#define int long long#define RI register int#define CI const int&usingnamespace std;
constint INF=1e18;
int t,n;
inlineintcalc(CI x){
int cnt=x,tmp=n;
while (tmp>0)
{
int y; if (tmp>=x-1) y=x-1;
else {
y=tmp;
if (y%2!=(x-1)%2) --y;
}
if (y==0) return INF;
cnt+=tmp/y; tmp-=tmp/y*y;
}
return cnt;
}
signedmain(){
for (scanf("%lld",&t);t;--t)
{
scanf("%lld",&n); int ans=INF;
int l=max(2LL,(int)sqrt(n)-5),r=(int)sqrt(n)+5;
for (RI i=l;i<=r;++i) ans=min(ans,calc(i));
printf("%lld\n",ans);
}
return0;
}
from math import gcd
T = int(input())
for t inrange(T):
n = int(input())
a = list(map(int, input().split()))
min_a = min(a)
if min_a == max(a):
print(0)
continue g = 0for i inrange(1, n):
g = gcd(g, a[i] - min_a)
print(g)
10|0Friends
拿个 two pointers 随便搞一搞就过了
#include<bits/stdc++.h>intmain(){
std::ios::sync_with_stdio(false);
int n, m;
std::cin >> n >> m;
std::vector<std::vector<int>> fd(n + 1);
for(int i = 1, u, v; i <= m; ++i) {
std::cin >> u >> v;
fd[v].push_back(u);
}
int l = 0;
int ans = 0;
for(int i = 1; i <= n; ++i) {
auto &fs = fd[i];
fs.push_back(i);
std::sort(fs.begin(), fs.end());
int cc = 0;
for(int j = 0; j < fs.size() - 1; ++j) if(fs[j] < fs[j + 1] - 1) cc = j + 1;
ans += i - (l = std::max(l, fs[cc])) + 1;
// std::cout << l << ", " << i << char(10); }
std::cout << ans << char(10);
return0;
}
11|0Zero
徐神太有实力了,直接用随机过程的方法淦过去了,我一点听不懂做法
大致思路就是求出以每个点为右端点时,连续的 1 的数量的期望,然后一波神秘拆贡献计算即可
#include<bits/stdc++.h>using llsi = longlongsignedint;
constexpr llsi mod = 998244353;
constexpr llsi ksm(llsi a, llsi b){
llsi res = 1;
while(b) {
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
constexpr llsi inv2 = ksm(2, mod - 2);
llsi C[32][32], p[100001], e[100001][32], B[32][32];
intmain(){
std::ios::sync_with_stdio(false);
int n, K; std::cin >> n >> K;
for(int i = 0; i <= 31; ++i) C[i][0] = 1;
for(int i = 1; i <= 31; ++i) for(int j = 1; j <= i; ++j)
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
std::string s; std::cin >> s;
for(int i = 1; i <= n; ++i) {
switch(s[i - 1]) {
case'0': p[i] = 0; break;
case'1': p[i] = 1; break;
case'?': p[i] = inv2; break;
}
}
for(int i = 0; i <= n; ++i) e[i][0] = 1;
for(int i = 1; i <= n; ++i) for(int k = 1; k <= K + 1; ++k) {
for(int j = 0; j <= k; ++j) {
e[i][k] += C[k][j] * e[i - 1][j] % mod;
}
e[i][k] = e[i][k] % mod * p[i] % mod;
}
// for(int i = 1; i <= n; ++i) std::cout << e[i][K] << char(i == n ? 10 : 32); B[0][1] = 1;
for(int k = 1; k <= K + 1; ++k) {
for(int j = 1; j <= k + 1; ++j) B[k][j] = C[k + 1][j];
for(int j = 0; j <= k - 1; ++j) {
for(int l = 0; l <= j + 1; ++l)
B[k][l] += mod - B[j][l] * C[k + 1][j] % mod;
}
for(int j = 0; j <= k + 1; ++j) B[k][j] = B[k][j] % mod * ksm(k + 1, mod - 2) % mod;
}
// for(int i = 1; i <= K + 1; ++i)// for(int j = 0; j <= i + 1; ++j)// std::cout << B[i][j] << char(j == i + 1 ? 10 : 32); llsi ans = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= K + 1; ++j)
ans += e[i][j] * B[K][j] % mod;
}
std::cout << ans % mod << char(10);
return0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
2020-07-25 LOJ #6059. 「2017 山东一轮集训 Day1」Sum
2020-07-25 Luogu P3721 [AH2017/HNOI2017]单旋
2020-07-25 Luogu P3336 [ZJOI2013]话旧