QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#936469#10226. Tree Fliptritr (Keita Murase, Rin Saiki, Ryuto Kojima)#AC ✓119ms30988kbC++2322.1kb2025-03-15 20:26:062025-03-15 20:26:08

Judging History

This is the latest submission verdict.

  • [2025-03-15 20:26:08]
  • Judged
  • Verdict: AC
  • Time: 119ms
  • Memory: 30988kb
  • [2025-03-15 20:26:06]
  • Submitted

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