QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#222652 | #7610. Bus Lines | ucup-team087# | WA | 18ms | 11784kb | C++20 | 21.4kb | 2023-10-21 17:54:51 | 2023-10-21 17:54:53 |
Judging History
answer
#ifndef LOCAL
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#define si(x) int(x.size())
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif
template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}
template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;
using pi=pair<int,int>;
using vi=vc<int>;
template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
return os<<"{"<<p.a<<","<<p.b<<"}";
}
template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
os<<"{";
for(auto e:v)os<<e<<",";
return os<<"}";
}
#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
os<<t<<" ";
dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif
using uint=unsigned;
using ull=unsigned long long;
template<class t,size_t n>
ostream& operator<<(ostream&os,const array<t,n>&a){
return os<<vc<t>(all(a));
}
template<int i,class T>
void print_tuple(ostream&,const T&){
}
template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
if(i)os<<",";
os<<get<i>(t);
print_tuple<i+1,T,Args...>(os,t);
}
template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
os<<"{";
print_tuple<0,tuple<Args...>,Args...>(os,t);
return os<<"}";
}
ll read(){
ll i;
cin>>i;
return i;
}
vi readvi(int n,int off=0){
vi v(n);
rep(i,n)v[i]=read()+off;
return v;
}
pi readpi(int off=0){
int a,b;cin>>a>>b;
return pi(a+off,b+off);
}
template<class t>
void print_single(t x,int suc=1){
cout<<x;
if(suc==1)
cout<<"\n";
if(suc==2)
cout<<" ";
}
template<class t,class u>
void print_single(const pair<t,u>&p,int suc=1){
print_single(p.a,2);
print_single(p.b,suc);
}
template<class T>
void print_single(const vector<T>&v,int suc=1){
rep(i,v.size())
print_single(v[i],i==int(v.size())-1?suc:2);
}
template<class T>
void print_offset(const vector<T>&v,ll off,int suc=1){
rep(i,v.size())
print_single(v[i]+off,i==int(v.size())-1?suc:2);
}
template<class T,size_t N>
void print_single(const array<T,N>&v,int suc=1){
rep(i,N)
print_single(v[i],i==int(N)-1?suc:2);
}
template<class T>
void print(const T&t){
print_single(t);
}
template<class T,class ...Args>
void print(const T&t,const Args&...args){
print_single(t,2);
print(args...);
}
string readString(){
string s;
cin>>s;
return s;
}
template<class T>
T sq(const T& t){
return t*t;
}
void YES(bool ex=true){
cout<<"YES\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void NO(bool ex=true){
cout<<"NO\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void Yes(bool ex=true){
cout<<"Yes\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void No(bool ex=true){
cout<<"No\n";
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
//#define CAPITAL
/*
void yes(bool ex=true){
#ifdef CAPITAL
cout<<"YES"<<"\n";
#else
cout<<"Yes"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void no(bool ex=true){
#ifdef CAPITAL
cout<<"NO"<<"\n";
#else
cout<<"No"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}*/
void possible(bool ex=true){
#ifdef CAPITAL
cout<<"POSSIBLE"<<"\n";
#else
cout<<"Possible"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
void impossible(bool ex=true){
#ifdef CAPITAL
cout<<"IMPOSSIBLE"<<"\n";
#else
cout<<"Impossible"<<"\n";
#endif
if(ex)exit(0);
#ifdef LOCAL
cout.flush();
#endif
}
constexpr ll ten(int n){
return n==0?1:ten(n-1)*10;
}
const ll infLL=LLONG_MAX/3;
#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif
int topbit(signed t){
return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
return t==0?-1:63-__builtin_clzll(t);
}
int topbit(ull t){
return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
return a==0?64:__builtin_ctzll(a);
}
int botbit(ull a){
return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
return __builtin_popcount(t);
}
int popcount(ll t){
return __builtin_popcountll(t);
}
int popcount(ull t){
return __builtin_popcountll(t);
}
int bitparity(ll t){
return __builtin_parityll(t);
}
bool ispow2(int i){
return i&&(i&-i)==i;
}
ll mask(int i){
return (ll(1)<<i)-1;
}
ull umask(int i){
return (ull(1)<<i)-1;
}
ll minp2(ll n){
if(n<=1)return 1;
else return ll(1)<<(topbit(n-1)+1);
}
bool inc(int a,int b,int c){
return a<=b&&b<=c;
}
template<class t> void mkuni(vc<t>&v){
sort(all(v));
v.erase(unique(all(v)),v.ed);
}
ll rand_int(ll l, ll r) { //[l, r]
//#ifdef LOCAL
static mt19937_64 gen;
/*#else
static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
#endif*/
return uniform_int_distribution<ll>(l, r)(gen);
}
ll rand_int(ll k){ //[0,k)
return rand_int(0,k-1);
}
template<class t>
void myshuffle(vc<t>&a){
rep(i,si(a))swap(a[i],a[rand_int(0,i)]);
}
template<class t>
int lwb(const vc<t>&v,const t&a){
return lower_bound(all(v),a)-v.bg;
}
template<class t>
bool bis(const vc<t>&v,const t&a){
return binary_search(all(v),a);
}
vvc<int> readGraph(int n,int m){
vvc<int> g(n);
rep(i,m){
int a,b;
cin>>a>>b;
//sc.read(a,b);
a--;b--;
g[a].pb(b);
g[b].pb(a);
}
return g;
}
vvc<int> readTree(int n){
return readGraph(n,n-1);
}
template<class t>
vc<t> presum(const vc<t>&a){
vc<t> s(si(a)+1);
rep(i,si(a))s[i+1]=s[i]+a[i];
return s;
}
vc<ll> presum(const vi&a){
vc<ll> s(si(a)+1);
rep(i,si(a))s[i+1]=s[i]+a[i];
return s;
}
//BIT で数列を管理するときに使う (CF850C)
template<class t>
vc<t> predif(vc<t> a){
gnr(i,1,si(a))a[i]-=a[i-1];
return a;
}
template<class t>
vvc<ll> imos(const vvc<t>&a){
int n=si(a),m=si(a[0]);
vvc<ll> b(n+1,vc<ll>(m+1));
rep(i,n)rep(j,m)
b[i+1][j+1]=b[i+1][j]+b[i][j+1]-b[i][j]+a[i][j];
return b;
}
//verify してないや
void transvvc(int&n,int&m){
swap(n,m);
}
template<class t,class... Args>
void transvvc(int&n,int&m,vvc<t>&a,Args&...args){
assert(si(a)==n);
vvc<t> b(m,vi(n));
rep(i,n){
assert(si(a[i])==m);
rep(j,m)b[j][i]=a[i][j];
}
a.swap(b);
transvvc(n,m,args...);
}
//CF854E
void rotvvc(int&n,int&m){
swap(n,m);
}
template<class t,class... Args>
void rotvvc(int&n,int&m,vvc<t>&a,Args&...args){
assert(si(a)==n);
vvc<t> b(m,vi(n));
rep(i,n){
assert(si(a[i])==m);
rep(j,m)b[m-1-j][i]=a[i][j];
}
a.swap(b);
rotvvc(n,m,args...);
}
//ソートして i 番目が idx[i]
//CF850C
template<class t>
vi sortidx(const vc<t>&a){
int n=si(a);
vi idx(n);iota(all(idx),0);
sort(all(idx),[&](int i,int j){return a[i]<a[j];});
return idx;
}
//vs[i]=a[idx[i]]
//例えば sortidx で得た idx を使えば単にソート列になって返ってくる
//CF850C
template<class t>
vc<t> a_idx(const vc<t>&a,const vi&idx){
int n=si(a);
assert(si(idx)==n);
vc<t> vs(n);
rep(i,n)vs[i]=a[idx[i]];
return vs;
}
//CF850C
vi invperm(const vi&p){
int n=si(p);
vi q(n);
rep(i,n)q[p[i]]=i;
return q;
}
template<class t,class s=t>
s SUM(const vc<t>&a){
return accumulate(all(a),s(0));
}
template<class t>
t MAX(const vc<t>&a){
return *max_element(all(a));
}
template<class t>
pair<t,int> MAXi(const vc<t>&a){
auto itr=max_element(all(a));
return mp(*itr,itr-a.bg);
}
template<class t>
t MIN(const vc<t>&a){
return *min_element(all(a));
}
template<class t>
pair<t,int> MINi(const vc<t>&a){
auto itr=min_element(all(a));
return mp(*itr,itr-a.bg);
}
vi vid(int n){
vi res(n);iota(all(res),0);
return res;
}
template<class S>
void soin(S&s){
sort(all(s));
}
template<class S>
S soout(S s){
soin(s);
return s;
}
template<class S>
void rein(S&s){
reverse(all(s));
}
template<class S>
S reout(S s){
rein(s);
return s;
}
template<class t,class u>
pair<t,u>&operator+=(pair<t,u>&a,pair<t,u> b){
a.a+=b.a;a.b+=b.b;return a;}
template<class t,class u>
pair<t,u>&operator-=(pair<t,u>&a,pair<t,u> b){
a.a-=b.a;a.b-=b.b;return a;}
template<class t,class u>
pair<t,u> operator+(pair<t,u> a,pair<t,u> b){return mp(a.a+b.a,a.b+b.b);}
template<class t,class u>
pair<t,u> operator-(pair<t,u> a,pair<t,u> b){return mp(a.a-b.a,a.b-b.b);}
template<class t>
t gpp(vc<t>&vs){
assert(si(vs));
t res=move(vs.back());
vs.pop_back();
return res;
}
template<class t>
void pb(vc<t>&a,const vc<t>&b){
a.insert(a.ed,all(b));
}
template<class t>
vc<t> cat(vc<t> a,const vc<t>&b){
pb(a,b);
return a;
}
template<class t,class u>
vc<t>& operator+=(vc<t>&a,u x){
for(auto&v:a)v+=x;
return a;
}
template<class t,class u>
vc<t> operator+(vc<t> a,u x){
return a+=x;
}
template<class t,class u>
vc<t>& operator-=(vc<t>&a,u x){
for(auto&v:a)v-=x;
return a;
}
template<class t,class u>
vc<t>& operator-(vc<t> a,u x){
return a-=x;
}
//内部でグラフをいじるから in,out を使うときは注意
//hei[v] -> heavy edge で潜っていった時,自分含めて何個あるか
//pe[v]: v->par[v] の辺の情報
//-有向木のときは上から下の辺を入れてる
//-無向木のときは下から上の辺を入れてる
//VERIFY: yosupo
//CF530F
//CodeChef Persistent Oak
//AOJ GRL5C
template<class E>
struct HLD{
vvc<E> g;
int n,rt,cnt;
vi sub,in,out,par,head,dep,hei,ni;
vc<E> pe;
int dfs1(int v,int p,int d){
par[v]=p;
dep[v]=d;
for(auto itr=g[v].bg;itr!=g[v].ed;itr++)
if(*itr==p){
pe[v]=*itr;
g[v].erase(itr);
break;
}
for(auto&e:g[v]){
pe[e]=e;
sub[v]+=dfs1(e,v,d+1);
if(sub[g[v][0]]<sub[e])
swap(g[v][0],e);
}
return sub[v];
}
void dfs2(int v,int h){
in[v]=cnt++;
head[v]=h;
for(int to:g[v])
dfs2(to,to==g[v][0]?h:to);
out[v]=cnt;
if(si(g[v]))hei[v]=hei[g[v][0]]+1;
}
HLD(){}
HLD(const vvc<E>&gg,int rr):g(gg),n(g.size()),rt(rr),cnt(0),
sub(n,1),in(n),out(n),par(n,-1),head(n),dep(n),hei(n,1),ni(n),
pe(n){
dfs1(rt,-1,0);
dfs2(rt,rt);
rep(i,n)ni[in[i]]=i;
}
int lca(int a,int b){
while(head[a]!=head[b]){
if(dep[head[a]]>dep[head[b]])
swap(a,b);
b=par[head[b]];
}
if(dep[a]>dep[b])
swap(a,b);
return a;
}
int len(int a,int b){
return dep[a]+dep[b]-dep[lca(a,b)]*2;
}
bool asde(int a,int b){
return in[a]<=in[b]&&out[b]<=out[a];
}
//UCUP 1-22 F
int adv(int a,int d){
if(hei[a]<=d)return -1;
else return ni[in[a]+d];
}
//CF692F
int getpar(int v,int len){
assert(dep[v]>=len);
int tar=dep[v]-len;
while(1){
int h=head[v];
if(dep[h]<=tar){
return ni[in[h]+(tar-dep[h])];
}
v=par[h];
}
assert(false);
}
//1st UCUP 13 G
int jump(int a,int b,int d){
int c=lca(a,b);
if(d<=(dep[a]-dep[c])){
return getpar(a,d);
}else{
d=(dep[a]+dep[b]-dep[c]*2)-d;
assert(d>=0);
return getpar(b,d);
}
}
//XX Opencup GP of Korea
//CF625 F
//2020 Multi-Uni Contest Day5 G
//CF415E
//Universal Cup 2023 Stage 1 G
vi index;
//vs を含む virtual tree を返す
//返すのは virtual tree に使われた頂点と,辺の集合
//辺の端点は,virtual tree における番号
//元の木における番号を virtual tree の頂点番号に写すのが,index という変数
//辺は ch->par の順
//virtual tree は行き掛け順で番号がついている
//特に,頂点 0 が根になるようにできている
//pair<vi,vc<pi>> tree_compress(vi vs){
void tree_compress(vi&vs,vc<pi>&es){
if(si(index)==0)index.resize(n);
assert(index.size());
auto comp = [&](int x,int y){
return in[x] < in[y];
};
sort(all(vs),comp);
//assert(is_sorted(all(vs),comp));
vs.erase(unique(all(vs)),vs.ed);
int k = vs.size();
rep(i,k-1){
vs.pb(lca(vs[i],vs[i+1]));
}
sort(all(vs),comp);
vs.erase(unique(all(vs)),vs.ed);
k = vs.size();
rep(i,k) index[vs[i]] = i;
es.clear();
rng(i,1,k){
int p = lca(vs[i-1],vs[i]);
es.eb(i,index[p]);
}
//return mp(vs,es);
}
//assume a is desdendant of b
//ex=true <=> exclude b
template<class F>
void subpath_work(int a,int b,bool ex,F f){
while(1){
if(head[a]==head[b]){
f(in[b]+ex,in[a]+1);
break;
}else{
int h=head[a];
f(in[h],in[a]+1);
a=par[h];
}
}
}
//KUPC2021E
//パスに対する操作順に注意
//euler-tour 順にしたときの区間に作用していることに注意
//ex=true exclude lca(a,b) (=apply path edges)
template<class F>
void path_work(int a,int b,bool ex,F f){
int c=lca(a,b);
subpath_work(a,c,ex,f);
subpath_work(b,c,true,f);
}
//root-v パス上で f(x)=true となる最も深い頂点を返す
//CF857G
template<class F>
int find_lowest(int v,F f){
while(v>=0){
int h=head[v];
if(!f(h)){
v=par[h];
}else{
int l=0,r=dep[v]-dep[h]+1;
while(r-l>1){
const int mid=(l+r)/2;
if(f(ni[in[h]+mid]))l=mid;
else r=mid;
}
return ni[in[h]+l];
}
}
return -1;
}
};
struct E{
int to,idx;
operator int()const{
return to;
}
};
template<class t>
struct BIT{
vc<t> buf;
int s;
BIT(int n=0){init(n);}
BIT(const vc<t>&a){init(a);}
void init(int n){buf.clear();buf.resize(s=n);}
void init(const vc<t>&a){
s=si(a);
buf.resize(s);
rep(i,s)buf[i]=a[i];
rep(i,s){
int j=i+((i+1)&(-i-1));
if(j<s)buf[j]+=buf[i];
}
}
void add(int i,t v){
for(;i<s;i+=(i+1)&(-i-1))
buf[i]+=v;
}
t get(int i){
t res=t();
for(;i>=0;i-=(i+1)&(-i-1))
res+=buf[i];
return res;
}
t sum(int b,int e){
return get(e-1)-get(b-1);
}
void add_range(int b,int e,t v){
add(b,v);
add(e,-v);
}
int kth(int k){
int res=0;
for(int i=topbit(s);i>=0;i--){
int w=res+(1<<i);
if(w<=s&&buf[w-1]<=k){
k-=buf[w-1];
res=w;
}
}
return res;
}
//yukicoder No.1024
int kth_helper(int k,int i){
return kth(k+get(i-1));
}
};
// bit op
int popcnt(uint x) { return __builtin_popcount(x); }
int popcnt(ull x) { return __builtin_popcountll(x); }
int bsr(uint x) { return 31 - __builtin_clz(x); }
int bsr(ull x) { return 63 - __builtin_clzll(x); }
int bsf(uint x) { return __builtin_ctz(x); }
int bsf(ull x) { return __builtin_ctzll(x); }
struct FastSet {
static constexpr uint B = 64;
int n, lg;
vvc<ull> seg;
FastSet(int _n,ull val=0) : n(_n) {
do {
seg.push_back(vc<ull>((_n + B - 1) / B,val));
_n = (_n + B - 1) / B;
} while (_n > 1);
lg = seg.size();
}
void fillone(){
for(auto&vs:seg)fill(all(vs),ull(-1));
}
void fillzero(){
for(auto&vs:seg)fill(all(vs),ull(0));
}
bool operator[](int i) const {
return (seg[0][i / B] >> (i % B) & 1) != 0;
}
void set(int i) {
for (int h = 0; h < lg; h++) {
seg[h][i / B] |= 1ULL << (i % B);
i /= B;
}
}
void reset(int i) {
for (int h = 0; h < lg; h++) {
seg[h][i / B] &= ~(1ULL << (i % B));
if (seg[h][i / B]) break;
i /= B;
}
}
// x以上最小の要素
int next(int i) {
for (int h = 0; h < lg; h++) {
if (i / B == si(seg[h])) break;
ull d = seg[h][i / B] >> (i % B);
if (!d) {
i = i / B + 1;
continue;
}
// find
i += bsf(d);
for (int g = h - 1; g >= 0; g--) {
i *= B;
i += bsf(seg[g][i / B]);
}
return i;
}
return n;
}
// x未満最大の要素
int prev(int i) {
i--;
for (int h = 0; h < lg; h++) {
if (i == -1) break;
ull d = seg[h][i / B] << (63 - i % 64);
if (!d) {
i = i / B - 1;
continue;
}
// find
i += bsr(d) - (B - 1);
for (int g = h - 1; g >= 0; g--) {
i *= B;
i += bsr(seg[g][i / B]);
}
return i;
}
return -1;
}
};
//VERIFY: yosupo
//KUPC2017J
//AOJDSL1A
//without rank
struct unionfind{
vi p,s;
int c;
unionfind(int n):p(n,-1),s(n,1),c(n){}
void clear(){
fill(all(p),-1);
fill(all(s),1);
c=si(p);
}
int find(int a){
return p[a]==-1?a:(p[a]=find(p[a]));
}
//set b to a child of a
bool unite(int a,int b){
a=find(a);
b=find(b);
if(a==b)return false;
p[b]=a;
s[a]+=s[b];
c--;
return true;
}
bool same(int a,int b){
return find(a)==find(b);
}
int sz(int a){
return s[find(a)];
}
};
bool dbg=false;
void slv(){
int n;cin>>n;
auto torg=readTree(n);
HLD<int> hld(torg,0);
const auto&t=hld.g;
int m;cin>>m;
vvc<pi> ls(n);
vi up=vid(n);
auto upupd=[&](int v,int to){
if(hld.dep[to]<hld.dep[up[v]])
up[v]=to;
};
rep(_,m){
int a,b;cin>>a>>b;
a--;b--;
int c=hld.lca(a,b);
if(hld.in[a]>hld.in[b])swap(a,b);
if(a!=c&&b!=c){
ls[c].eb(a,b);
}
upupd(a,c);
upupd(b,c);
}
for(auto i:reout(hld.ni)){
if(i)upupd(hld.par[i],up[i]);
}
vvc<int> come(n);
rng(i,1,n)come[up[i]].pb(i);
vi easy(n);
{
vi cnt(n,1);
for(int i:reout(hld.ni)){
if(i)cnt[up[i]]+=cnt[i];
}
for(int i:reout(hld.ni)){
if(i)cnt[hld.par[i]]+=cnt[i];
}
dmp(cnt);
vi x(n),y(n);
rep(i,n){
int csum=0;
for(auto j:t[i]){
csum+=cnt[j];
}
for(auto j:t[i]){
x[j]+=csum-cnt[j];
y[j]+=hld.sub[i]-hld.sub[j];
}
easy[i]+=csum;
}
for(int i:hld.ni){
if(i){
x[i]+=x[hld.par[i]];
y[i]+=y[hld.par[i]];
}
}
for(int i:hld.ni){
if(i){
y[i]+=y[up[i]];
}
}
rep(i,n)easy[i]+=x[i]+y[i];
}
vi hard(n);
{
unionfind uf(n);
vi dif(n+1);
vi cnt(n,1);
for(int i:reout(hld.ni)){
if(i)cnt[up[i]]+=cnt[i];
}
for(int i:hld.ni){
if(i)cnt[i]+=cnt[hld.par[i]];
}
for(auto root:reout(hld.ni)){
if(si(ls[root])){
static vi vs;vs.clear();
static vc<pi> es;
for(auto&[a,b]:ls[root]){
a=uf.find(a);
b=uf.find(b);
vs.pb(a);
vs.pb(b);
}
hld.tree_compress(vs,es);
assert(vs[0]==root);
int s=si(vs);
//vs を含む virtual tree を返す
//返すのは virtual tree に使われた頂点と,辺の集合
//辺の端点は,virtual tree における番号
//元の木における番号を virtual tree の頂点番号に写すのが,index という変数
//辺は ch->par の順
//virtual tree は行き掛け順で番号がついている
//特に,頂点 0 が根になるようにできている
vvc<int> horg(s);
for(auto [i,j]:es){
horg[j].pb(i);
}
HLD<int> z(horg,0);
const auto&h=z.g;
vvc<int> other(s);
for(auto [a,b]:ls[root]){
a=hld.index[a];
b=hld.index[b];
other[a].pb(b);
other[b].pb(a);
}
vi val(s);
for(auto i:z.ni){
val[i]=cnt[vs[i]];
}
FastSet fs(s);
int have=0;
auto adddif=[&](int v,int w){
int top=0;
{
int j=fs.prev(z.in[v]);
if(j>=0){
j=z.lca(z.ni[j],v);
if(z.dep[top]<z.dep[j])
top=j;
}
}
{
int j=fs.next(z.in[v]+1);
if(j<s){
j=z.lca(z.ni[j],v);
if(z.dep[top]<z.dep[j])
top=j;
}
}
have+=(val[v]-val[top])*w;
};
auto use=[&](int v){
adddif(v,1);
fs.set(z.in[v]);
};
auto unuse=[&](int v){
fs.reset(z.in[v]);
adddif(v,-1);
};
auto dfs=[&](auto self,int v,bool clean)->void{
per(i,si(h[v])){
int to=h[v][i];
self(self,to,i>0);
}
for(auto u:other[v])use(u);
int a=vs[v],b=vs[z.par[v]];
hld.subpath_work(a,b,true,[&](int l,int r){
dif[l]+=have;
dif[r]-=have;
});
if(clean){
rng(i,z.in[v],z.out[v])
//unuse(z.ni[i]);
for(auto u:other[z.ni[i]])
unuse(u);
}
};
for(auto v:h[0])dfs(dfs,v,true);
}
for(auto i:come[root]){
uf.unite(hld.par[i],i);
}
}
rep(i,n)dif[i+1]+=dif[i];
vi w(n);
rep(i,n)w[i]=dif[hld.in[i]];
for(int i:hld.ni){
if(i)w[i]+=w[up[i]];
}
rep(i,n)hard[i]+=w[i];
}
dmp(easy);
dmp(hard);
vi ans(n);
rep(i,n)ans[i]=easy[i]-hard[i];
print(ans);
}
signed main(){
cin.tie(0);
ios::sync_with_stdio(0);
cout<<fixed<<setprecision(20);
if(dbg){
while(1)slv();
}else{
//int t;cin>>t;rep(_,t)
slv();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3612kb
input:
6 1 2 5 4 6 5 3 1 1 5 3 6 1 2 3 6 4
output:
6 9 9 10 7 7
result:
ok single line: '6 9 9 10 7 7'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3484kb
input:
2 1 2 1 1 2
output:
1 1
result:
ok single line: '1 1'
Test #3:
score: -100
Wrong Answer
time: 18ms
memory: 11784kb
input:
16384 9137 490 3442 7239 1621 6904 13769 10250 14672 12572 14906 9437 6163 12339 15244 12016 3022 8670 3211 9106 11966 14817 15798 15876 6423 7394 894 7695 13877 1983 16342 15158 13574 15932 15125 10722 6989 15683 10335 8801 12301 4246 6166 3893 9347 12073 7897 12195 6510 3101 4526 15385 7017 7001 4...
output:
34355 15446187 2060840 3438382 158435 2693945 900528 2356422 2106076 381932 384811 3433163 2624990 2619013 294549 963672 2200750 267508 20768564 361071 5547546 415917 131487 9480752 1122271 762491 137673 222586 1095537 1289975 3067629 412528 1754883 429843 1602905 42019 233381 916048 2288538 3430460...
result:
wrong answer 1st lines differ - expected: '34355 34048 34070 34152 33992 ...5 34333 33814 33294 34266 34337', found: '34355 15446187 2060840 3438382...9 2192738 624763 2746003 641779'