zoukankan      html  css  js  c++  java
  • [cf715C]Digit Tree

    不断将统计当前这颗子树到之前所有子树的路径并合并,考虑以前的路径为x,当前的路径为y,最终答案即$x\cdot 10^{len(y)}\equiv 0(mod\ p)$,转化为$x\equiv -y/10^{len(y)}(mod\ p)$,对于当前每一个y,查询之前x的个数(用map)即可,注意顺读和逆读的区别。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<map>
     5 using namespace std;
     6 #define ll long long
     7 #define maxN 100001
     8 #define pd (edge[i].to!=fa)&&(!vis[edge[i].to])
     9 map<int,int>mat,mat2;
    10 struct ji{
    11     int nex,to,len;
    12 }edge[maxN<<1];
    13 ll E,n,m,x,y,z,ans,head[maxN],pow[maxN],siz[maxN],ny[maxN];
    14 bool vis[maxN];
    15 void add(int x,int y,int z){
    16     edge[E].nex=head[x];
    17     edge[E].to=y;
    18     edge[E].len=z;
    19     head[x]=E++;
    20 }
    21 ll ksm(ll n,ll t){
    22     if (!t)return 1LL;
    23     ll s=ksm(n,t>>1);
    24     s=s*s%m;
    25     if (t&1)s=s*n%m;
    26     return s;
    27 }
    28 int size(int k,int fa){
    29     siz[k]=1;
    30     for(int i=head[k];i!=-1;i=edge[i].nex)
    31         if (pd)siz[k]+=size(edge[i].to,k);
    32     return siz[k];
    33 }
    34 int query(int k,int fa,int n){
    35     int ma=0,p;
    36     for(int i=head[k];i!=-1;i=edge[i].nex)
    37         if (pd)
    38             if (p=query(edge[i].to,k,n))return p;
    39             else ma=max(1LL*ma,siz[edge[i].to]);
    40     ma=max(1LL*ma,n-siz[k]);
    41     if (ma<=n/2)return k;
    42     return 0;
    43 }
    44 void calc(int k,int fa,int dep,ll s,ll s2){
    45     ans+=mat[(m-s2*ny[++dep]%m)%m]+mat2[s];
    46     for(int i=head[k];i!=-1;i=edge[i].nex)
    47         if (pd)calc(edge[i].to,k,dep,(s+edge[i].len*pow[dep])%m,(s2*10+edge[i].len)%m);
    48 }
    49 void tot(int k,int fa,int dep,ll s,ll s2){
    50     mat[s]++;
    51     mat2[(m-s2*ny[++dep]%m)%m]++;
    52     for(int i=head[k];i!=-1;i=edge[i].nex)
    53         if (pd)tot(edge[i].to,k,dep,(s+edge[i].len*pow[dep])%m,(s2*10+edge[i].len)%m);
    54 }
    55 void dfs(int k,int fa){
    56     int r=query(k,fa,size(k,fa));
    57     mat.clear();
    58     mat2.clear();
    59     mat[0]=mat2[0]=1;
    60     for(int i=head[r];i!=-1;i=edge[i].nex)
    61         if (pd){
    62             calc(edge[i].to,r,0,edge[i].len,edge[i].len);
    63             tot(edge[i].to,r,0,edge[i].len,edge[i].len);
    64         }
    65     vis[r]=true;
    66     for(int i=head[r];i!=-1;i=edge[i].nex)
    67         if (pd)dfs(edge[i].to,r);
    68     vis[r]=false;
    69     mat.clear();
    70     mat2.clear();
    71     mat[0]=mat2[0]=1;
    72     tot(k,fa,0,0,0);
    73     vis[r]=true;
    74 }
    75 int main(){
    76     memset(head,-1,sizeof(head));
    77     scanf("%lld%lld",&n,&m);
    78     for(int i=1;i<n;i++){
    79         scanf("%lld%lld%lld",&x,&y,&z);
    80         z%=m;
    81         add(++x,++y,z);
    82         add(y,x,z);
    83     }
    84     x=y=m;
    85     for(int i=2;1LL*i*i<=m;i++)
    86         if (y%i==0){
    87             x=x/i*(i-1);
    88             while (y%i==0)y/=i;
    89         }
    90     if (y>1)x=x/y*(y-1);
    91     for(int i=0;i<=n;i++)pow[i]=ksm(10,i);
    92     for(int i=0;i<=n;i++)ny[i]=ksm(pow[i],x-1);
    93     dfs(1,0);
    94     printf("%lld",ans);
    95 }
    View Code
  • 相关阅读:
    Windows SDK编程(Delphi版) 之 应用基础,楔子
    一个小问题引发的论证思考
    Delphi 组件开发教程指南(7)继续模拟动画显示控件
    用PyInstaller将python转成可执行文件exe笔记
    使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)
    Microsof Office SharePoint 2007 工作流开发环境搭建
    How to monitor Web server performance by using counter logs in System Monitor in IIS
    LINQ之Order By
    window 性能监视器
    内存泄露检测工具
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11254619.html
Copyright © 2011-2022 走看看