• [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
  • 相关阅读:
    WPF MarkupExtension
    WPF Binding小数,文本框不能输入小数点的问题
    WPF UnhandledException阻止程序奔溃
    .Net Core的总结
    C#单元测试
    Csla One or more properties are not registered for this type
    unomp 矿池运行问题随记
    矿池负载运行监测记录
    MySql 数据库移植记录
    后台服务运行后无故停止运行,原因不明
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11254619.html
Copyright © 2020-2023  润新知