题解:P17724 [SCP-S 2026] 路短最 / path
nullptr_qwq_ · · 题解
很好写的做法,甚至不用圆方树。
令
每个含
维护 map 启发式合并即可 map 的总操作次数仍然是
时间复杂度
写的时候发现只需要在 map 的
#include<bits/stdc++.h>
#define bll __int128
#define ull unsigned long long
#define ll long long
#define uint unsigned
#define pb push_back
#define mkp make_pair
#define fi first
#define se second
#define inf 1073741824
#define infll 1000000000000000000ll
#define pii pair<int,int>
#define rep(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define per(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define F(i,a,b) for(int i=a,i##end=b;i<=i##end;i++)
#define dF(i,a,b) for(int i=a,i##end=b;i>=i##end;i--)
#define SZ(x) ((int)x.size())
#define all(x) x.begin(),x.end()
using namespace std;
bool ST;
void fre(){
// freopen(".in","r",stdin),freopen(".out","w",stdout);
}
inline int lowbit(int x){ return x&(-x); }
template<typename T>inline void chkmax(T &x,const T &y){ x=std::max(x,y); }
template<typename T>inline void chkmin(T &x,const T &y){ x=std::min(x,y); }
const int mod=998244353,maxn=2000005;
int testid,n,zsy;
struct ds{
map<int,ll>mp;
int tag;
ll su;
void init(){
mp.clear(),tag=su=0;
}
void add(int pos,ll val){
mp[pos-tag]+=val,su+=val;
}
void trans(int x){
if(x<=0||mp.empty())return;
auto R=mp.upper_bound(x-tag);
for(auto it=mp.begin();it!=R;++it)mp.emplace((it->fi)-x,it->se),su+=it->se;
tag+=x;
}
}f[maxn];
void merge(ds&a,ds&b){
if(SZ(a.mp)<SZ(b.mp))a.mp.swap(b.mp),swap(a.tag,b.tag),swap(a.su,b.su);
a.su+=b.su;
for(auto it=b.mp.begin();it!=b.mp.end();++it)a.mp[(it->fi)+b.tag-a.tag]+=it->se;
}
int dfn[maxn],rev[maxn],tim,fa[maxn];
vector<int>g[maxn];
void dfs0(int u){
rev[dfn[u]=++tim]=u;
for(int&v:g[u])if(!dfn[v])fa[v]=u,dfs0(v);
}
bool inr[maxn];
int a[maxn],up[maxn];
void solve(){
cin>>n>>zsy,tim=0;
F(i,1,n)g[i].clear(),fa[i]=inr[i]=dfn[i]=a[i]=up[i]=0,f[i].init();
F(_,1,zsy){ int u,v;cin>>u>>v,g[u].push_back(v),g[v].push_back(u); }
dfs0(1);
F(u,1,n)for(int&v:g[u])if(dfn[v]<dfn[u]&&v!=fa[u]){
vector<int>vec;
for(int x=u;x!=v;x=fa[x])inr[x]=1,vec.push_back(x);
reverse(all(vec));
bool fl=vec[0]<vec.back();
int len=SZ(vec);
F(i,0,len-1){
int x=fl?vec[i]:vec[len-1-i];
up[x]=v,a[x]=(((i+1)<<1)>len+1&&i+1<len)?((i+1)<<1)-(len+1):0;
}
}
F(i,2,n)if(!inr[i])a[i]=0,up[i]=fa[i];
dF(_,n,1){
const int u=rev[_];
f[u].add(1,1);
if(u==1)break;
if(a[u])f[u].trans(a[u]);
merge(f[up[u]],f[u]);
map<int,ll>().swap(f[u].mp);
}
cout<<f[1].su<<'\n';
}
bool ED;
signed main(){
fre(),ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int zsy=1;cin>>testid>>zsy;
F(____,1,zsy)solve();
cerr<<"time used: "<<(double)clock()/CLOCKS_PER_SEC<<endl;
cerr<<"memory used: "<<abs(&ST-&ED)/1024.0/1024.0<<" MB"<<endl;
}
// g++ C.cpp -o a -std=c++14 -O2