tjut 4661

来源:互联网 发布:淘宝买家怎么开店 编辑:程序博客网 时间:2024/05/29 16:05
#pragma comment(linker,"/STACK:100000000,100000000")  #include <stdio.h>  #define LL __int64    const int mod = 1000000007;  const int maxn = 1000003;  struct EDGE{      int to, next;  }edge[maxn*2];    int head[maxn], E, cnt[maxn];  LL jie[maxn], mul[maxn];    void init(int n) {      for(int i = 1;i <= n; i++)  head[i] = -1;      E = 0;  }    void newedge(int u, int to) {      edge[E].to = to;      edge[E].next = head[u];      head[u] = E++;  }    LL modstyle(LL x) {  // 取余操作,由于取余%很慢的,这样写效率比较好      if(x >= mod)    x %= mod;      else if(x < 0) {          x = (x%mod+mod)%mod;      }      return x;  }  //  扩展欧几里得  求逆元  LL exgcd(LL a ,LL b, LL &x, LL &y) {      if(b == 0) {          x = 1; y = 0;          return a;;      }      LL ans = exgcd(b, a%b, y, x);      y = y - a/b*x;      return ans;  }  //  求组合数 C(n,k)  LL cal(int n, int k) {      LL x, y;      LL d = exgcd(jie[n-k]*jie[k], mod, x, y);      x = modstyle(x);      return jie[n]*x%mod;  }  //  第一次DFS统计出每个节点的所有的子树的总结点数cnt[u],子树节点信息传到该节点的情况数mul[u]  void dfs1(int u, int pre) {      cnt[u] = 0;      mul[u] = 1;      for(int i = head[u];i != -1;i = edge[i].next) {          int to = edge[i].to;          if(to != pre) {              dfs1(to, u);              cnt[u] += cnt[to]+1;              mul[u] = modstyle(mul[u]*mul[to]);          }      }      int sum = cnt[u];      for(int i = head[u];i != -1;i = edge[i].next) {          int to = edge[i].to;          if(to != pre) {              mul[u] = modstyle(mul[u]*cal(sum, cnt[to]+1)); //   对于子树的情况利用组合数进行汇聚              sum -= cnt[to]+1;          }      }  }    LL ans = 0;  int n;    void dfs2(int u, int pre) {      if(pre != -1) {  //   父节点的信息传到该节点进行更新计算          LL x, y;          LL d = exgcd(cal(n-1, cnt[u]+1), mod, x, y);          x = modstyle(x);          LL cur = mul[pre]*x%mod;          cur = cur*cal(n-1, cnt[u])%mod;          mul[u] = cur;          ans = (ans + cur*cur)%mod;      }      for(int i = head[u];i != -1;i = edge[i].next) {          int to = edge[i].to;          if(to != pre) {              dfs2(to, u);          }      }  }    int main() {      int i, t, u, to;      jie[0] = 1;      for(i = 1;i <= 1000000; i++) {          jie[i] = modstyle(jie[i-1]*i);      }      scanf("%d", &t);      while(t--) {          scanf("%d", &n);          if(n == 1) {              puts("1");              continue;          }          init(n);          for(i = 0;i < n-1; i++) {              scanf("%d%d", &u, &to);              newedge(u, to);              newedge(to, u);          }          dfs1(1, -1);          ans = mul[1]*mul[1]%mod;          dfs2(1, -1);          printf("%I64d\n", ans);      }      return 0;  }  

0 0
原创粉丝点击