QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#936469 | #10226. Tree Flip | tritr (Keita Murase, Rin Saiki, Ryuto Kojima)# | AC ✓ | 119ms | 30988kb | C++23 | 22.1kb | 2025-03-15 20:26:06 | 2025-03-15 20:26:08 |
Judging History
answer
//#define _GLIBCXX_DEBUG
//#pragma GCC target("avx2")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include <debug_print.hpp>
#define OUT(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define OUT(...) (static_cast<void>(0))
#endif
#define endl '\n'
#define lfs cout<<fixed<<setprecision(15)
#define ALL(a) (a).begin(),(a).end()
#define ALLR(a) (a).rbegin(),(a).rend()
#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
namespace template_tute{
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 4.1e18;
using P = pair<ll, ll>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max<ll>({a,b,c})-min<ll>({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}
template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};
template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};
template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};
template<typename T>void debug(const vector<T>&v){debug(v,v.size());}
template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}
template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}
template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}
template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << "(" << p.first << "," << p.second << ")";}
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){os<<"[";for(auto &z:v)os << z << ",";os<<"]"; return os;}
template<typename T>void rearrange(vector<int>&ord, vector<T>&v){
auto tmp = v;
for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];
}
template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){
rearrange(ord, head);
rearrange(ord, tail...);
}
template<typename T> vector<int> ascend(const vector<T>&v){
vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],i)<make_pair(v[j],j);});
return ord;
}
template<typename T> vector<int> descend(const vector<T>&v){
vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],-i)>make_pair(v[j],-j);});
return ord;
}
template<typename T> vector<T> inv_perm(const vector<T>&ord){
vector<T>inv(ord.size());
for(int i=0;i<ord.size();i++)inv[ord[i]] = i;
return inv;
}
ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}
ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}
ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}
ll modulo(ll n,ll d){return (n%d+d)%d;};
template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}
template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}
template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};
template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int popcount(ll x){return __builtin_popcountll(x);};
int poplow(ll x){return __builtin_ctzll(x);};
int pophigh(ll x){return 63 - __builtin_clzll(x);};
template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};
template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};
ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}
ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}
ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}
std::ostream &operator<<(std::ostream &dest, __int128_t value) {
std::ostream::sentry s(dest);
if (s) {
__uint128_t tmp = value < 0 ? -value : value;
char buffer[128];
char *d = std::end(buffer);
do {
--d;
*d = "0123456789"[tmp % 10];
tmp /= 10;
} while (tmp != 0);
if (value < 0) {
--d;
*d = '-';
}
int len = std::end(buffer) - d;
if (dest.rdbuf()->sputn(d, len) != len) {
dest.setstate(std::ios_base::badbit);
}
}
return dest;
}
namespace converter{
int dict[500];
const string lower="abcdefghijklmnopqrstuvwxyz";
const string upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string digit="0123456789";
const string digit1="123456789";
void regi_str(const string &t){
for(int i=0;i<t.size();i++){
dict[t[i]]=i;
}
}
void regi_int(const string &t){
for(int i=0;i<t.size();i++){
dict[i]=t[i];
}
}
vector<int>to_int(const string &s,const string &t){
regi_str(t);
vector<int>ret(s.size());
for(int i=0;i<s.size();i++){
ret[i]=dict[s[i]];
}
return ret;
}
vector<int>to_int(const string &s){
auto t=s;
sort(t.begin(),t.end());
t.erase(unique(t.begin(),t.end()),t.end());
return to_int(s,t);
}
vector<vector<int>>to_int(const vector<string>&s,const string &t){
regi_str(t);
vector<vector<int>>ret(s.size(),vector<int>(s[0].size()));
for(int i=0;i<s.size();i++){
for(int j=0;j<s[0].size();j++){
ret[i][j]=dict[s[i][j]];
}
}
return ret;
}
vector<vector<int>>to_int(const vector<string>&s){
string t;
for(int i=0;i<s.size();i++){
t+=s[i];
}
sort(t.begin(),t.end());t.erase(unique(t.begin(),t.end()),t.end());
return to_int(s,t);
}
string to_str(const vector<int>&s,const string &t){
regi_int(t);
string ret;
for(auto z:s)ret+=dict[z];
return ret;
}
vector<string> to_str(const vector<vector<int>>&s,const string &t){
regi_int(t);
vector<string>ret(s.size());
for(int i=0;i<s.size();i++){
for(auto z:s[i])ret[i]+=dict[z];
}
return ret;
}
}
template< typename T = int >
struct edge {
int to;
T cost;
int id;
edge():to(-1),id(-1){};
edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}
operator int() const { return to; }
};
template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
Graph<T>revgraph(const Graph<T> &g){
Graph<T>ret(g.size());
for(int i=0;i<g.size();i++){
for(auto e:g[i]){
int to = e.to;
e.to = i;
ret[to].push_back(e);
}
}
return ret;
}
template<typename T>
Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){
Graph<T> ret(n);
for(int es = 0; es < m; es++){
int u,v;
T w=1;
cin>>u>>v;u-=indexed,v-=indexed;
if(weighted)cin>>w;
ret[u].emplace_back(v,w,es);
if(!directed)ret[v].emplace_back(u,w,es);
}
return ret;
}
template<typename T>
Graph<T> readParent(int n,int indexed=1,bool directed=true){
Graph<T>ret(n);
for(int i=1;i<n;i++){
int p;cin>>p;
p-=indexed;
ret[p].emplace_back(i);
if(!directed)ret[i].emplace_back(p);
}
return ret;
}
}
using namespace template_tute;
template<typename T>
struct HLD{
using D=long long;
int n;
vector<int>sz;//部分木サイズ
vector<D>dep;
vector<int>par;
vector<int>head;
Graph<T> &g;//隣接リスト
vector<edge<T>>edges;//データ構造に乗せるedge列
vector<int>in,out;//[in,out)で部分木、[ina,inb]でa~bのパス(aが上)
vector<int>comp;//連結成分の根
//inは頂点のindexを表す。また、edge列の下側の頂点である
HLD(Graph<T> &g,int r=-1):g(g),n(g.size()){
hld_build(r);
}
void hld_build(int root = -1){
in.assign(n,-1);out.assign(n,-1);dep.assign(n,0);
par.assign(n,-1);head.assign(n,-1);sz.assign(n,-1);comp.assign(n,-1);
edges.assign(n,edge<T>());
if(root == -1){//根がどこでも良い場合(森でも可)
for(int i=0;i<n;i++){
if(sz[i] == -1){
head[i] = i;
dfs_sz(i, 0, i);
dfs_hld(i);
}
}
}
else{
head[root] = root;
dfs_sz(root, 0, root);
dfs_hld(root);
}
}
void dfs_sz(int k, D d,int r){
sz[k] = 1;
comp[k] = r;
dep[k] = d;
for(auto &e: g[k]){
if(e.to == par[k])continue;
par[e.to] = k;
dfs_sz(e.to, d+e.cost, r);
sz[k] += sz[e.to];
if(g[k][0].to==par[k]||sz[e.to] > sz[g[k][0].to])swap(e, g[k][0]);
}
}
int time = 0;
void dfs_hld(int k){
in[k] = time++;
for(auto e:g[k]){
if(e.to == par[k])continue;
head[e.to] = (e.to == g[k][0].to ? head[k]: e.to);
edges[time] = e;
dfs_hld(e.to);
}
out[k] = time;
}
int lca(int p,int q){
while(1){
if(in[p] < in[q])swap(p,q);
if(head[p] == head[q])return q;
p = par[head[p]];
}
}
vector<pair<int,int>>query_path(int p,int q,bool isEdge){
int r=lca(p,q);
vector<pair<int,int>>ret;
for(int i=0;i<2;i++){
if(i == 1)swap(p,q);
while(1){
if(isEdge&&p==r)break;
if(head[p]==head[r]){
ret.emplace_back(in[r]+(isEdge?1:i),in[p]+1);
break;
}
ret.emplace_back(in[head[p]],in[p]+1);
p = par[head[p]];
}
}
return ret;
}
vector<vector<pair<int,int>>>query_order_path(int p,int q,bool isEdge){
//非可換クエリ用、配列0を順番を反転したデータ構造に、配列1を通常のデータ構造に
vector<vector<pair<int,int>>>ret(2);
int r=lca(p,q);
for(int i=0;i<2;i++){
if(i == 1)swap(p,q);
while(1){
if(isEdge&&p==r)break;
if(head[p]==head[r]){
if(i==0) ret[i].emplace_back(n-(in[p]+1),n-(in[r]+(isEdge?1:i)));
else ret[i].emplace_back(in[r]+(isEdge?1:i),in[p]+1);
break;
}
if(i==0) ret[i].emplace_back(n-(in[p]+1),n-(in[head[p]]));
else ret[i].emplace_back(in[head[p]],in[p]+1);
p = par[head[p]];
}
}
reverse(ret[1].begin(), ret[1].end());
return ret;
}
pair<int,int>query_subtree(int p,bool isEdge){
return make_pair(in[p]+isEdge,out[p]);
}
//uのv方向の子 子孫関係は前もって確認すること(in,outを見る)
int child(int u,int v)const{
while(1){
if(head[u]==head[v]){
v=g[u][0].to;
break;
}
v=head[v];
if(par[v]==u)break;
v=par[v];
}
return v;
}
//uをv方向に一つ進めた頂点
int move(int u,int v)const{
assert(u!=v);
if(in[u]<in[v]&&in[v]<out[u])return child(u,v);
else return par[u];
}
D dist(int u,int v){
return dep[u]+dep[v]-2*dep[lca(u,v)];
}
vector<int>rev_in;
int climb(int u,int k){
if(rev_in.empty()){
rev_in.resize(n);
for(int i=0;i<n;i++)rev_in[in[i]]=i;
}
int nd=max<int>(dep[u]-k, 0);
while(dep[u]>nd){
if(dep[head[u]]>nd){
u=par[head[u]];
}
else{
u=rev_in[in[head[u]]+nd-dep[head[u]]];
}
}
return u;
}
int jump(int from,int to, int k){
int r = lca(from, to);
int d1 = dep[from] - dep[r];
int d2 = dep[to] - dep[r];
if(d1 + d2 < k)return -1;
else if(k <= d1)return climb(from, k);
else return climb(to, d1 + d2 - k);
}
template<typename I>
Graph<T>lca_tree(vector<I>&v){
auto compare=[&](int x,int y){return in[x]<in[y];};
sort(v.begin(),v.end(),compare);
int sz1=v.size();
for(int i=0;i<sz1-1;i++)v.push_back(lca(v[i],v[i+1]));
sort(v.begin(),v.end(),compare);
v.erase(unique(v.begin(),v.end()),v.end());
int sz2=v.size();
Graph<T>ret(sz2);
stack<int>st;
for(int i=0;i<sz2;i++){
while(!st.empty()&&out[v[st.top()]]<=in[v[i]])st.pop();
if(!st.empty()){
ret[st.top()].emplace_back(i,dep[v[i]]-dep[v[st.top()]]);
ret[i].emplace_back(st.top(),dep[v[i]]-dep[v[st.top()]]);
}
st.push(i);
}
return ret;
}
};
const int VERTEX = 0;
const int HEAVY_LIGHT = -1;
const int LIGHT = -2;
const int HEAVY = -3;
template<typename T>
struct StaticToptree{
const HLD<T> &hld;
int count;
int root;
vector<int>l,r,p;
vector<int>aff;
T edge_identity;
StaticToptree(const HLD<T> &hld):hld(hld),edge_identity(edge_identity),count(hld.n),l(hld.n*2-1,-1),r(hld.n*2-1,-1),p(hld.n*2-1,-1),aff(hld.n*2-1,VERTEX){
int hld_root=min_element(hld.in.begin(),hld.in.end())-hld.in.begin();
root = dfs(hld_root,-1).second;
}
//sz,vid
pair<int,int>dfs(int v,int par){
int sub=0;
vector<int>vs;
vector<int>sz;
int now=v,pre=par;
while(1){
int sum_sz=1;
//vid,eid
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>pq;
for(int i=1;i<hld.g[now].size();i++){
if(hld.g[now][i].to==pre)continue;
auto [sz, vid] = dfs(hld.g[now][i].to, now);
pq.emplace(sz,vid);
sum_sz+=sz;
}
sub+=sum_sz;
while(pq.size()>=2){
auto [sx,x]=pq.top();pq.pop();
auto [sy,y]=pq.top();pq.pop();
int nv=count++;
aff[nv]=LIGHT;
l[nv]=x;
p[x]=nv;
r[nv]=y;
p[y]=nv;
pq.emplace(sx+sy,nv);
}
int last=now;
if(!pq.empty()){
auto [sx,x]=pq.top();pq.pop();
int nv=count++;
aff[nv]=HEAVY_LIGHT;
l[nv]=now;
p[x]=nv;
r[nv]=x;
p[now]=nv;
last=nv;
}
vs.push_back(last);
sz.push_back(sum_sz);
if(hld.g[now].empty()||hld.g[now][0]==pre)break;
pre=now;
now=hld.g[now][0];
}
vector<int>csz(sz.size()+1);
for(int i=0;i<sz.size();i++){
csz[i+1]=csz[i]+sz[i];
}
auto rec=[&](auto &&rec,int ls,int rs)->int {
if(ls+1==rs){
return vs[ls];
}
int sum=csz[rs]-csz[ls];
int lv=-1,rv=-1;
if(sz[ls]*2>=sum){
lv=rec(rec,ls,ls+1);
rv=rec(rec,ls+1,rs);
}
else if(sz[rs-1]*2>=sum){
lv=rec(rec,ls,rs-1);
rv=rec(rec,rs-1,rs);
}
else{
int ri=min<int>(rs-1,lower_bound(csz.begin()+ls,csz.begin()+rs,csz[ls]+(sum+1)/2)-csz.begin());
int li=max(ls+1,ri-1);
if(abs((csz[li]-csz[ls])*2-sum)<abs((csz[ri]-csz[ls])*2-sum)){
ri=li;
}
lv=rec(rec,ls,ri);
rv=rec(rec,ri,rs);
}
int nv=count++;
aff[nv]=HEAVY;
l[nv]=lv,p[lv]=nv;
r[nv]=rv,p[rv]=nv;
return nv;
};
int last=rec(rec,0,sz.size());
return make_pair(sub,last);
}
};
template<typename T,typename V,typename F1,typename F2,typename F3>
struct DynamicReRooting{
const StaticToptree<T> &t;
vector<V>seg,ges;
const F1 &fh;
const F2 &fl;
const F3 &fhl;
const V M1;
vector<int>path;
DynamicReRooting(const StaticToptree<T> &t,const F1 &heavy_merge,const F2 &light_merge,const F3 &heavy_light_merge,const V M1):
t(t),fh(heavy_merge),fl(light_merge),fhl(heavy_light_merge),M1(M1){
seg.assign(t.aff.size(),M1);
ges.assign(t.aff.size(),M1);
}
void set(int k,V val){
seg[k]=val;
ges[k]=val;
}
void recalc(int k){
if(t.aff[k]==LIGHT){
seg[k]=fl(seg[t.l[k]],seg[t.r[k]]);
}
else if(t.aff[k]==HEAVY){
seg[k]=fh(seg[t.l[k]],seg[t.r[k]]);
ges[k]=fh(ges[t.r[k]],ges[t.l[k]]);
}
else if(t.aff[k]==HEAVY_LIGHT){
seg[k]=fhl(seg[t.l[k]],seg[t.r[k]]);
ges[k]=seg[k];
}
}
void build(){
for(int i=0;i<t.aff.size();i++){
recalc(i);
}
}
void update(int k,V val){
seg[k]=val;
ges[k]=val;
while(t.p[k]!=-1){
k=t.p[k];
recalc(k);
}
}
int root_path(int k){
int cnt=0;
while(1){
if(cnt>=path.size())path.push_back(0);
path[cnt++]=k;
if(t.p[k]==-1)break;
k=t.p[k];
}
return cnt;
}
//head,tail,light
tuple<V,V,V>get(int k){
int m=root_path(k);
V head=M1,tail=M1,light=M1;
int hl=-1;
for(int i=m-1;i>=1;i--){
if(t.aff[path[i]]==HEAVY){
if(t.l[path[i]]==path[i-1]){
tail=fh(seg[t.r[path[i]]],tail);
}
else{
auto lt=ges[t.l[path[i]]];
head=fh(ges[t.l[path[i]]],head);
}
}
else if(t.aff[path[i]]==HEAVY_LIGHT){
if(i==1&&k==t.l[path[i]])light=seg[t.r[path[i]]];
else hl=t.l[path[i]];
}
else{
//LIGHT
if(t.l[path[i]]==path[i-1]){
light=fl(seg[t.r[path[i]]],light);
}
else{
light=fl(seg[t.l[path[i]]],light);
}
}
if(hl!=-1&&t.aff[path[i-1]]!=LIGHT){
head=fhl(seg[hl],fl(light,fl(head,tail)));
tail=M1;
light=M1;
hl=-1;
}
}
return make_tuple(head,tail,light);
}
V reroot(int r){
auto [head,tail,light]=get(r);
return fhl(seg[r],fl(light,fl(head,tail)));
}
V reroot(int r,int k){
if(r==k)return reroot(r);
r=t.hld.move(k,r);
if(r==t.hld.par[k]){
auto [head,tail,light]=get(k);
return fhl(seg[k],fl(light,tail));
}
else{
auto [head,tail,light]=get(r);
return head;
}
}
V prod_root(){
return seg.back();
}
template<typename PF>
void print(PF printer){
vector<vector<int>>vst(t.aff.size());
for(int i=0;i<t.aff.size();i++){
if(t.aff[i]==VERTEX){
vst[i].push_back(i);
cout<<"[VERTEX]: "<<i<<endl;
}
else if(t.aff[i]==HEAVY){
vst[i]=vst[t.l[i]];
vst[i].insert(vst[i].end(),vst[t.r[i]].begin(),vst[t.r[i]].end());
cout<<"[HEAVY]: ";for(auto v:vst[i])cout<<v<<" ";cout<<endl;
}
else if(t.aff[i]==LIGHT){
for(auto v:{t.l[i],t.r[i]}){
if(t.aff[v]==LIGHT)vst[i].insert(vst[i].end(),vst[v].begin(),vst[v].end());
else vst[i].push_back(vst[v][0]);
}
cout<<"[LIGHT]: ";for(auto v:vst[i])cout<<v<<" ";cout<<endl;
}
else{
vst[i].push_back(vst[t.l[i]][0]);
cout<<"[HL]: "<<vst[i][0]<<" exclude: "<<t.hld.g[vst[i][0]][0].to<<endl;
}
printer(seg[i]);
}
}
};
void solve(){
ll res=0,buf=0;
bool judge = true;
ll n,q;cin>>n>>q;
vector<ll>a(n);
rep(i,0,n)cin>>a[i];
auto g=readGraph<ll>(n,n-1);
HLD<ll> hld(g);
StaticToptree<ll> t(hld);
struct S{
ll pref,cnt0,cnt1;
};
auto fh=[&](S h,S t)->S {
if(h.pref)swap(t.cnt0,t.cnt1);
return S{h.pref^t.pref,h.cnt0+t.cnt0,h.cnt1+t.cnt1};
};
auto fl=[&](S x,S y)->S {
return S{0,x.cnt0+y.cnt0,x.cnt1+y.cnt1};
};
auto fhl=[&](S h,S t)->S {
if(h.pref)swap(t.cnt0,t.cnt1);
return S{h.pref,h.cnt0+t.cnt0,h.cnt1+t.cnt1};
};
S ident={0,0,0};
auto get=[&](ll v)->S {
if(v==0)return S{0,1,0};
else return S{1,0,1};
};
DynamicReRooting seg(t,fh,fl,fhl,ident);
for(int i=0;i<n;i++){
seg.set(i,get(a[i]));
}
seg.build();
ll root=0;
OUT(a);
while(q--){
ll type,x;cin>>type>>x;x--;
if(type==1){
a[x]^=1;
seg.update(x,get(a[x]));
}
else{
root=x;
}
auto val=seg.reroot(root);
OUT(a,root,val.cnt0,val.cnt1,val.pref);
cout<<val.cnt1<<endl;
}
}
int main(){
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
ll res=0,buf=0;
bool judge = true;
int T = 1;
cin>>T;
while(T--){
solve();
}
return 0;
}
这程序好像有点Bug,我给组数据试试?
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3712kb
input:
1 3 3 0 0 1 1 2 3 1 1 1 2 2 1 1
output:
2 1 1
result:
ok 3 lines
Test #2:
score: 0
Accepted
time: 119ms
memory: 30988kb
input:
1 100000 100000 0 0 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 0 1 0 0 1 0 0 1 0 1 0 0 1 1 1 0 1 1 1 1 0 1 1 ...
output:
49874 50073 49944 49944 49917 49916 49984 49947 49945 49870 50089 50088 50024 50025 49980 49862 49984 49982 49983 49990 49949 49951 49950 50195 50196 50196 49955 50072 50071 49993 50021 50134 49985 49917 49886 49885 50134 49818 49819 49952 49954 49955 49986 50046 50018 50021 50020 50017 50130 50132 ...
result:
ok 100000 lines
Test #3:
score: 0
Accepted
time: 75ms
memory: 5964kb
input:
10 9141 9858 1 1 1 0 0 1 1 1 0 0 1 1 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 1 0 1 1 0 0 0 0 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1 0 1 0 0 1 0 0 1 0 1 0 0 1 0 1 1 0 1 1...
output:
4598 4606 4568 4553 4529 4529 4601 4600 4534 4546 4548 4621 4597 4515 4586 4586 4587 4536 4552 4553 4555 4556 4618 4580 4555 4561 4549 4547 4547 4517 4594 4593 4556 4556 4554 4554 4553 4557 4603 4603 4602 4602 4600 4516 4523 4593 4592 4589 4590 4591 4584 4543 4542 4532 4537 4562 4611 4558 4556 4591 ...
result:
ok 95405 lines
Test #4:
score: 0
Accepted
time: 61ms
memory: 7124kb
input:
10 9997 9996 1 1 1 0 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 0 0 1 1 1 0 1 0 0 0 1 1 1 0 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0 0 0 1 1 0 0 1 0 0 1 0 1 1 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1...
output:
4997 5001 4990 5018 5024 5011 5042 5066 4955 4971 4971 4937 4947 4983 5050 4971 5038 5038 4960 5032 4966 4924 4999 4957 5041 5041 4957 4973 5000 5025 4998 5015 5016 5020 5006 5020 5015 5036 5008 5008 4975 4996 4957 4986 5051 4998 5004 4990 4990 4965 4995 4963 4987 5009 4989 5007 5007 4985 4998 5007 ...
result:
ok 99942 lines
Test #5:
score: 0
Accepted
time: 35ms
memory: 3584kb
input:
10000 10 10 0 1 0 1 1 0 0 0 0 1 3 5 5 10 5 4 2 10 2 7 9 4 2 1 3 8 6 7 2 5 1 7 1 5 2 1 1 7 1 9 2 1 2 7 1 8 2 4 4 10 1 1 0 1 1 4 1 2 2 3 1 4 1 4 2 4 1 3 2 3 2 3 1 2 2 2 2 1 2 4 10 10 0 1 0 1 1 1 0 0 1 0 10 7 7 3 10 5 10 1 1 8 5 6 10 9 2 9 4 3 2 1 2 6 1 1 2 7 1 7 1 5 1 3 1 5 2 7 1 3 4 10 0 1 1 1 1 2 3 ...
output:
7 5 5 3 5 4 4 3 4 7 2 1 3 2 2 2 3 2 2 2 3 3 5 5 5 5 5 5 5 5 2 2 2 2 2 1 3 2 1 1 1 2 2 2 2 2 1 1 1 2 4 5 4 3 5 5 3 4 5 4 4 5 2 3 2 4 5 4 2 3 2 2 2 2 2 2 2 3 3 3 5 2 2 7 2 2 3 2 7 6 4 3 1 1 2 2 3 4 5 4 6 6 4 5 6 4 5 6 6 7 5 2 4 2 4 1 3 2 4 4 3 7 2 6 6 7 6 1 1 1 0 0 1 1 2 1 2 1 2 2 4 2 1 1 2 2 4 3 3 2 ...
result:
ok 100000 lines
Extra Test:
score: 0
Extra Test Passed