hdu 4812 Tree partition + + inverse handwriting hashmap

a * b% mod == k equivalent to k * inv (b)% mod == a

Then partition the tree, you can record with hashmap, unorder_map / map looks like will TLE, I hand a

Note that this inverse element may be small linear processing directly

The complexity of the $ nlogn * hashmap $

#include <bits / STDC ++ H.> 
#define LL Long Long 
#define REP (II, A, B) for (int = A II; <= B II; II ++) 
#define the IO :: iOS sync_with_stdio (to false) ; cin.tie (0); cout.tie (0) 
#define Fi First 
#define SE SECOND 
#define the make_pair MP 
#define pair PII <LL, LL> 
the using namespace STD; 
const int = 1e6 + MAXN 10, MAXM = 2E6 +10; 
const LL INF = 0x88888888, MOD = 1e6 +. 3; 
int CASN, n-, m, K; 
LL Val [MAXN], INV [MAXN]; 
const int. 9 + 4E6 = maxsz; // @ @ prime table: 3,3e7 + + + 19,2e7 1E7 23 
// 1e6 3,2e6 + + + 7,4e6 3,3e6 9,1e5 + + + 3,3e5 3,2e5 7,4e5 + 9 + 
// @ to guarantee this value is less than the number of operations maxsz, maxsz preferably prime @ 
// @ COUNT operation without adding a new node @ 
class hash_map {public:  
  struct {node LL U; V int, Next;} E [maxsz <<. 1];
  int head [maxsz], Nume, numk, ID [maxsz]; 
  BOOL COUNT (U LL) {
    int hs=u%maxsz;
    for(int i=head[hs];i;i=e[i].next)
      if(e[i].u==u) return 1;
    return 0;
  }
  int& operator[](ll u){
    int hs=u%maxsz;
    for(int i=head[hs];i;i=e[i].next)
      if(e[i].u==u) return e[i].v;
    if(!head[hs])id[++numk]=hs;
    return e[++nume]=(node){u,0,head[hs]},head[hs]=nume,e[nume].v;
  }
  void clear(){
    rep(i,0,numk)head[id[i]]=0;
    numk=nume=0;
  }
};

namespace graph{
  struct node{int to,next;}e[maxm];
  int head[maxn],nume,all,vis[maxn],root,maxt;
  int sz[maxn];
  void add(int a,int b){
    e[++nume]={b,head[a]};
    head[a]=nume;
  }
  void init(int n){
    rep(i,0,n) vis[i]=head[i]=0;
    root=nume=1;
  }
  void getroot(int now,int fa){
    sz[now]=1;
    for(int i=head[now];i;i=e[i].next){
      int to=e[i].to;
      if(to==fa||vis[to]) continue;
      getroot(to,now);
      sz[now]+=sz[to];
    }
    int tmp=max(sz[now]-1,all-sz[now]);
    if(maxt>tmp) maxt=tmp,root=now;
  }//@基础部分@
  hash_map p;
  int dfn;
  pii stree[maxn];
  pii ans;
  int flag;
  void dfs(int now,int fa,ll dis){
    stree[++dfn]=mp(dis,now);
    for(int i=head[now];i;i=e[i].next){
      int to=e[i].to;
      if(to==fa||vis[to]) continue;
      dfs(to,now,dis*val[to]%mod);  
    }
  }
  void cal(int now,int root){
    dfn=0;
    dfs(now,now,val[now]);
    rep(i,1,dfn){
      ll x=k*inv[stree[i].fi]%mod;
      if(p.count(x)){
        pii tmp=mp(p[x],stree[i].se);
        if(tmp.fi>tmp.se) swap(tmp.fi,tmp.se);
        if(tmp.fi<ans.fi||tmp.fi==ans.fi&&tmp.se<ans.se) ans=tmp;
        flag=1;
      }
    }
    rep(i,1,dfn){
      (stree[i].fi*=val[root])%=mod;
      int &x=p[stree[i].fi];
      if(!x) x=stree[i].se;
      else if(x>stree[i].se)x=stree[i].se;
    }
  }
  void getans(int now){
    vis[now]=1;p.clear();
    p[val[now]]=now;
    for(int i=head[now];i;i=e[i].next){
      int to=e[i].to;
      if(vis[to]) continue;
      cal(to,now);
    }
    for(int i=head[now];i;i=e[i].next){
      int to=e[i].to;
      if(vis[to]) continue;
      all=sz[to],maxt=n+1;
      getroot(to,now);getans(root);
    }
  }
  void solve(int n){
    flag=0;maxt=all=n;
    ans=mp(1e9,1e9);
    getroot(1,1);
    getans(root);
  }
}using namespace graph;
namespace fastio{//@支持读取整数,字符串,输出整数@
bool isdigit(char c){return c>=48&&c<=57;}
const int maxsz=1e7;
class fast_iostream{public:
  char ch=get_char();
  bool endf=1,flag;
  char get_char(){
    static char buffer[maxsz],*a=buffer,*b=buffer;
    return b==a&&(b=(a=buffer)+fread(buffer,1,maxsz, stdin),b==a)?EOF:*a++;
  }
  template<typename type>bool get_int(type& tmp){
    flag=tmp=0;
    while(!isdigit(ch)&&ch!=EOF){flag=ch=='-';ch=get_char();};
    if(ch==EOF)return endf=0;
    do{tmp=ch-48+tmp*10;}while(isdigit(ch=get_char()));
    if(flag)tmp=-tmp;
    return 1;
  }
  int get_str(char* str){
    char* tmp=str;
    while(ch=='\r'||ch=='\n'||ch==' ')ch=get_char();
    if(ch==EOF)return(endf=0),*tmp=0;
    do{*(tmp++)=ch;ch=get_char();}while(ch!='\r'&&ch!='\n'&&ch!=' '&&ch!=EOF);
    *(tmp++)=0;
    return(int)(tmp-str-1);
  }
  fast_iostream& operator>>(char* tmp){get_str(tmp);return *this;}
  template<typename type>fast_iostream& operator>>(type& tmp){get_int(tmp);return *this;}
  operator bool() const {return endf;}
};
template<typename type>void put(type tmp){
  if (tmp==0){putchar(48);return;}
  static int top,stk[21];
  if (tmp<0){tmp=-tmp;putchar('-');}
  while(tmp)stk[++top]=tmp%10,tmp/=10;
  while(top)putchar(stk[top--]+48);
}
}fastio::fast_iostream io;
#define cin io
int main() {
  inv[1]=1;
  rep(i,2,v-1) { 
    INV [i] = (- v / i) * inv [v% i]% v + v;
    if(inv[i]<0) inv[i]+=mod;
  }
  while(cin>>n>>k){
    graph::init(n);
    rep(i,1,n) cin>>val[i];
    int a,b,c;
    rep(i,2,n){
      cin>>a>>b;
      graph::add(a,b);
      graph::add(b,a);
    }
    graph::solve(n);
    if(!flag) puts("No solution");
    else {
      if(ans.fi>ans.se) swap(ans.fi,ans.se);
      fastio::put(ans.fi);putchar(' ');
      fastio::put(ans.se);putchar('\n');
    }
  }
}

 Run pretty fast

 

Guess you like

Origin www.cnblogs.com/nervendnig/p/11582484.html