zoukankan      html  css  js  c++  java
  • [zoj3990]Tree Equation

    记$dep(T)$为树$T$的深度(根节点深度为0),则有$egin{cases}dep(A+B)=max(dep(A),dep(B))\dep(Acdot B)=dep(A)+dep(B)end{cases}$

    考虑$C$中最深的点,对其来源于$AX$还是$BY$分类讨论(不妨假设是前者),再取出其深度为$dep(A)$的祖先,那么$X$即只能取该祖先的子树

    确定$X$后,求出$AX$并在$C$中去掉,再类似地求出$Y$并判定即可

    过程中需要实现一个树同构的判定,简单哈希即可

    时间复杂度为$o(nlog n)$,可以通过

    (实现可能略微有一些繁琐,由于无法提交并不保证代码正确,仅供参考)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 100005
      4 #define mod 998244353
      5 #define ll long long
      6 int t,num[11],seed[N];
      7 map<int,vector<int> >mat;
      8 map<int,vector<int> >::iterator it;
      9 int read(){
     10     int x=0;
     11     char c=getchar();
     12     while ((c<'0')||(c>'9'))c=getchar();
     13     while ((c>='0')&&(c<='9')){
     14         x=x*10+c-'0';
     15         c=getchar();
     16     }
     17     return x;
     18 }
     19 void write(int x,char c=''){
     20     while (x){
     21         num[++num[0]]=x%10;
     22         x/=10;
     23     }
     24     if (!num[0])putchar('0');
     25     while (num[0])putchar(num[num[0]--]+'0');
     26     putchar(c);
     27 }
     28 struct Tree{
     29     int n,rt,mx,fa[N],dep[N],sz[N],f[N];
     30     vector<int>v[N];
     31     bool operator == (const Tree &T)const{
     32         return (sz[rt]==T.sz[T.rt])&&(f[rt]==T.f[T.rt]);
     33     }
     34     void Read(){
     35         for(int i=1;i<=n;i++)v[i].clear();
     36         for(int i=1;i<=n;i++){
     37             int x=read();
     38             if (!x)rt=i;
     39             else v[x].push_back(i);
     40         }
     41     }
     42     void Write(){
     43         for(int i=1;i<n;i++)write(fa[i],' ');
     44         write(fa[n],'
    ');
     45     }
     46     void dfs(int k,int s){
     47         dep[k]=s,sz[k]=f[k]=1;
     48         for(int i=0;i<v[k].size();i++){
     49             fa[v[k][i]]=k,dfs(v[k][i],s+1);
     50             sz[k]+=sz[v[k][i]];
     51             f[k]=(f[k]+(ll)f[v[k][i]]*seed[sz[v[k][i]]])%mod;
     52         }
     53     }
     54     void build(){
     55         fa[rt]=0,dfs(rt,0);
     56         mx=0;
     57         for(int i=1;i<=n;i++)mx=max(mx,dep[i]);
     58     }
     59     void get(Tree &T,int k,int f){
     60         int id=++T.n;
     61         T.v[id].clear();
     62         if (f)T.v[f].push_back(id); 
     63         for(int i=0;i<v[k].size();i++)get(T,v[k][i],id);
     64     }
     65 }A,B,C,X,Y,T,T0;
     66 void mul(Tree &A,Tree &B,Tree &T){
     67     T.n=A.n*B.n,T.rt=(A.rt-1)*B.n+1;
     68     for(int i=1;i<=T.n;i++)T.v[i].clear();
     69     for(int i=1;i<=A.n;i++){
     70         for(int j=0;j<A.v[i].size();j++)T.v[(i-1)*B.n+1].push_back((A.v[i][j]-1)*B.n+1);
     71         for(int j=1;j<=B.n;j++)
     72             for(int k=0;k<B.v[j].size();k++)T.v[(i-1)*B.n+j].push_back((i-1)*B.n+B.v[j][k]);
     73     }
     74 }
     75 bool dec(Tree &A,Tree &B,Tree &T){
     76     mat.clear();
     77     for(int i=0;i<A.v[A.rt].size();i++)mat[A.f[A.v[A.rt][i]]].push_back(A.v[A.rt][i]);
     78     T.n=T.rt=1,T.v[1].clear();
     79     for(int i=0;i<B.v[B.rt].size();i++){
     80         int x=B.f[B.v[B.rt][i]];
     81         if (mat[x].empty())return 0;
     82         mat[x].pop_back();
     83     }
     84     for(it=mat.begin();it!=mat.end();it++){
     85         vector<int>v=(*it).second;
     86         for(int i=0;i<v.size();i++)A.get(T,v[i],1);
     87     }
     88     return 1;
     89 }
     90 bool calc(){
     91     int pos;
     92     for(int i=0;i<=C.n;i++)
     93         if (C.dep[i]==C.mx)pos=i;
     94     while (C.dep[pos]!=A.mx)pos=C.fa[pos];
     95     X.n=0,X.rt=1,C.get(X,pos,0),X.build();
     96     if ((ll)A.n*X.n>C.n)return 0;
     97     mul(A,X,T),T.build();
     98     if (!dec(C,T,T0))return 0;
     99     T0.build();
    100     for(int i=0;i<=T0.n;i++)
    101         if (T0.dep[i]==T0.mx)pos=i;
    102     while (T0.dep[pos]!=B.mx)pos=T0.fa[pos];
    103     Y.n=0,Y.rt=1,T0.get(Y,pos,0),Y.build();
    104     if ((ll)B.n*Y.n!=T0.n)return 0;
    105     mul(B,Y,T),T.build();
    106     return T==T0;
    107 }
    108 int main(){
    109     srand(time(0));
    110     for(int i=0;i<N;i++)
    111         for(int j=0;j<60;j++)seed[i]=((seed[i]<<1)+rand()%2)%mod;
    112     t=read();
    113     while (t--){
    114         A.n=read(),B.n=read(),C.n=read();
    115         A.Read(),B.Read(),C.Read();
    116         A.build(),B.build(),C.build();
    117         if (calc()){
    118             write(X.n,' '),write(Y.n,'
    ');
    119             X.Write(),Y.Write();
    120             continue;
    121         }
    122         swap(A,B);
    123         if (!calc())printf("Impossible
    ");
    124         else{
    125             write(Y.n,' '),write(X.n,'
    ');
    126             Y.Write(),X.Write();
    127         }
    128     }
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    SAP MM模块教程(1)— 概述
    CodeSmith Generator
    EasyUI 左侧 tree 右侧 DataGrid模板
    C# 数据库访问公共类
    Easyui datagrid toolbar 模板
    EasyUI combogrid 更新查询参数 queryParams 重新加载
    Jenkins的搭建与使用
    Idea2020激活,全网最新教程(各版本通用),亲测2089!!!
    阿里云盘开启“个人云种子用户报名
    尚硅谷Java互联网大厂面试题第三季,1024干货
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15471284.html
Copyright © 2011-2022 走看看