zoukankan      html  css  js  c++  java
  • 后缀自动机

    理解起来好困难啊QAQ

    WIKIOI3160 求两个串的最长公共子串

    见CLJppt

     1 char s[maxn];
     2 struct sam
     3 {
     4     int n,last,cnt;
     5     int go[maxn][26],l[maxn],fa[maxn];
     6     void add(int x)
     7     {
     8         int p=last,np=last=++cnt;l[np]=l[p]+1;
     9         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
    10         if(!p)fa[np]=1;
    11         else 
    12         {
    13             int q=go[p][x];
    14             if(l[p]+1==l[q])fa[np]=q;
    15             else 
    16             {
    17                 int nq=++cnt;l[nq]=l[p]+1;
    18                 memcpy(go[nq],go[q],sizeof(go[q]));
    19                 fa[nq]=fa[q];
    20                 fa[np]=fa[q]=nq;
    21                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
    22             }
    23         }
    24     }    
    25     void init()
    26     {
    27         last=cnt=1;
    28         scanf("%s",s);int m=strlen(s);
    29         for0(i,m-1)add(s[i]-'a');
    30     }
    31     void solve()
    32     {
    33         scanf("%s",s);int m=strlen(s),now=1,t=0,ans=0;
    34         for0(i,m-1)
    35         {
    36             int x=s[i]-'a';
    37             if(go[now][x])t++,now=go[now][x];
    38             else 
    39             {
    40                 while(now&&!go[now][x])now=fa[now];
    41                 if(!now)t=0,now=1;
    42                 else t=l[now]+1,now=go[now][x];
    43             }
    44             ans=max(ans,t);
    45         }
    46         printf("%d
    ",ans);
    47     }
    48 }T;
    49 int main()
    50 {
    51     T.init();
    52     T.solve();
    53     return 0;
    54 }
    View Code

    BZOJ2555: SubString

    正解是SAM+LCT,但出题人显然没有卡暴力。。。写了个暴力结果跑了rank4 233

    犯了一个sb错就是没有更新lastQAQ

     1 char s[2*maxn];
     2 int mask;
     3 struct sam
     4 {
     5     int last,cnt,fa[maxn],go[maxn][26],l[maxn],r[maxn];
     6     sam(){last=cnt=1;}
     7     void add(int x)
     8     {
     9         int p=last,np=++cnt;last=np;l[np]=l[p]+1;
    10         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
    11         if(!p)fa[np]=1;
    12         else
    13         {
    14             int q=go[p][x];
    15             if(l[p]+1==l[q])fa[np]=q;
    16             else
    17             {
    18                 int nq=++cnt;l[nq]=l[p]+1;
    19                 memcpy(go[nq],go[q],sizeof(go[q]));
    20                 r[nq]=r[q];
    21                 fa[nq]=fa[q];
    22                 fa[q]=fa[np]=nq;
    23                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
    24             }
    25         }
    26         for(;np;np=fa[np])r[np]++;
    27     }
    28     void insert(char s[])
    29     {
    30         int n=strlen(s),t=mask;
    31         for0(i,n-1){mask=(mask*131+i)%n;swap(s[i],s[mask]);}
    32         mask=t;
    33         for0(i,n-1)add(s[i]-'A');
    34     }
    35     void query(char s[])
    36     {
    37         int n=strlen(s),now=1,t=mask;
    38         for0(i,n-1){mask=(mask*131+i)%n;swap(s[i],s[mask]);}
    39         for0(i,n-1)now=go[now][s[i]-'A'];
    40         mask=t^r[now];
    41         printf("%d
    ",r[now]);
    42     }
    43 }T;
    44 int main()
    45 {
    46     freopen("input.txt","r",stdin);
    47     freopen("output.txt","w",stdout);
    48     int Q=read();
    49     scanf("%s",s);int n=strlen(s);for0(i,n-1)T.add(s[i]-'A');
    50     while(Q--)
    51     {
    52         scanf("%s",s);
    53         if(s[0]=='A'){scanf("%s",s);T.insert(s);}
    54         else {scanf("%s",s);T.query(s);}
    55     }
    56     return 0;
    57 }
    View Code

    BZOJ3238: [Ahoi2013]差异

    后缀自动机其实反过来添加形成的parent树就是后缀树啦。

    写出后缀树DFS一遍就ok啦  妈妈我会写后缀树啦

     1 struct sam
     2 {
     3     int cnt,last,fa[maxn],go[maxn][26],head[maxn],l[maxn],s[maxn],tot;ll ans;
     4     char ch[maxn];
     5     struct edge{int go,next;}e[maxn];
     6     void add(int x)
     7     {
     8         int p=last,np=last=++cnt;l[np]=l[p]+1;
     9         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
    10         if(!p)fa[np]=1;
    11         else
    12         {
    13             int q=go[p][x];
    14             if(l[p]+1==l[q])fa[np]=q;
    15             else
    16             {
    17                 int nq=++cnt;l[nq]=l[p]+1;
    18                 memcpy(go[nq],go[q],sizeof(go[q]));
    19                 fa[nq]=fa[q];
    20                 fa[q]=fa[np]=nq;
    21                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
    22             }
    23         }
    24         s[np]=1;
    25     }
    26     void init()
    27     {
    28         last=cnt=1;
    29         scanf("%s",ch);int n=strlen(ch);ans=(ll)(n-1)*n*(n+1)/2;
    30         for3(i,n-1,0)add(ch[i]-'a');
    31     }
    32     void add(int x,int y)
    33     {
    34         e[++tot]=(edge){y,head[x]};head[x]=tot;
    35     }
    36     void dfs(int x)
    37     {
    38         for4(i,x)
    39         {
    40             dfs(y);
    41             ans-=(ll)2*s[y]*s[x]*l[x];
    42             s[x]+=s[y];
    43         }
    44     }
    45     void work()
    46     {
    47         for1(i,cnt)add(fa[i],i);
    48         dfs(1);
    49         cout<<ans<<endl;
    50     }
    51 }T;
    52 int main()
    53 {
    54     freopen("input.txt","r",stdin);
    55     freopen("output.txt","w",stdout);
    56     T.init();
    57     T.work();
    58     return 0;
    59 }
    View Code

    BZOJ2946: [Poi2000]公共串

    多个串的LCS。可以SA,也可以SAM。

    我们对每个节点保留mx[i][j]表示到i节点j串最多匹配多长,每个串做的时候就取max,然后这个节点对答案的贡献是min(),最后ans取max。

     1 int n;
     2 struct sam
     3 {
     4     int last,cnt,l[maxn],fa[maxn],go[maxn][26],mx[maxn][5];
     5     char s[maxn];
     6     void add(int x)
     7     {
     8         int p=last,np=last=++cnt;l[np]=l[p]+1;
     9         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
    10         if(!p)fa[np]=1;
    11         else
    12         {
    13             int q=go[p][x];
    14             if(l[p]+1==l[q])fa[np]=q;
    15             else
    16             {
    17                 int nq=++cnt;l[nq]=l[p]+1;
    18                 memcpy(go[nq],go[q],sizeof(go[q]));
    19                 fa[nq]=fa[q];
    20                 fa[q]=fa[np]=nq;
    21                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
    22             }
    23         }
    24     }
    25     void insert()
    26     {
    27         last=cnt=1;
    28         scanf("%s",s);int n=strlen(s);
    29         for0(i,n-1)add(s[i]-'a');
    30     }
    31     void work(int k)
    32     {
    33         scanf("%s",s);int n=strlen(s),now=1,t=0;
    34         for0(i,n-1)
    35         {
    36             int x=s[i]-'a';
    37             if(go[now][x]){t++;now=go[now][x];}
    38             else
    39             {
    40                 while(now&&!go[now][x])now=fa[now];
    41                 if(!now){t=0;now=1;}
    42                 else t=l[now]+1,now=go[now][x];
    43             }
    44             for(int j=now;j;j=fa[j])mx[j][k]=max(mx[j][k],t);
    45         }
    46     }
    47     void print()
    48     {
    49         int ans=0;
    50         for1(i,cnt)
    51         {
    52             int t=l[i];
    53             for0(j,n-1)t=min(t,mx[i][j]);
    54             ans=max(ans,t);
    55         }
    56         cout<<ans<<endl;
    57     }
    58 }T;            
    59 int main()
    60 {
    61     freopen("input.txt","r",stdin);
    62     freopen("output.txt","w",stdout);
    63     n=read();
    64     T.insert();
    65     for0(i,n-1)T.work(i);
    66     T.print();
    67     return 0;
    68 }
    View Code

    BZOJ3879: SvT

    构建出后缀树来就和差异那题一样了。1A简直感人肺腑。

      1 int n,m,a[maxn],id[maxn],v[maxn],top,sta[maxn],dep[maxn];
      2 ll ans;
      3 struct sam
      4 {
      5     int last,cnt,l[maxn],fa[maxn],head[maxn],go[maxn][26],tot,ti,dfn[maxn],f[maxn][20];
      6     struct edge{int go,next;}e[maxn];
      7     char s[maxn];
      8     void add(int x,int y)
      9     {
     10         e[++tot]=(edge){y,head[x]};head[x]=tot;
     11     }
     12     int add(int x)
     13     {
     14         int p=last,np=last=++cnt;l[np]=l[p]+1;
     15         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
     16         if(!p)fa[np]=1;
     17         else
     18         {
     19             int q=go[p][x];
     20             if(l[p]+1==l[q])fa[np]=q;
     21             else
     22             {
     23                 int nq=++cnt;l[nq]=l[p]+1;
     24                 memcpy(go[nq],go[q],sizeof(go[q]));
     25                 fa[nq]=fa[q];
     26                 fa[q]=fa[np]=nq;
     27                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
     28             }
     29         }
     30         return np;
     31     }
     32     int lca(int x,int y)
     33     {
     34         if(dep[x]<dep[y])swap(x,y);
     35         int t=dep[x]-dep[y];
     36         for0(i,18)if(t>>i&1)x=f[x][i];
     37         if(x==y)return x;
     38         for3(i,18,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
     39         return f[x][0];
     40     }
     41     void dfs(int x)
     42     {
     43         dfn[x]=++ti;
     44         for1(i,18)if(dep[x]>=1<<i)f[x][i]=f[f[x][i-1]][i-1];else break;
     45         for4(i,x)
     46         {
     47           dep[y]=dep[x]+1;f[y][0]=x;
     48           dfs(y);
     49         }
     50     }
     51     void init()
     52     {
     53         last=cnt=1;
     54         scanf("%s",s+1);int n=strlen(s+1);
     55         for3(i,n,1)id[i]=add(s[i]-'a');
     56         for1(i,cnt)add(fa[i],i);
     57         dfs(1);
     58     }
     59 }T;
     60 struct graph
     61 {
     62     int head[maxn],tot,s[maxn];
     63     struct edge{int go,next;}e[maxn];
     64     void add(int x,int y)
     65     {
     66         e[++tot]=(edge){y,head[x]};head[x]=tot;
     67     }
     68     void dfs(int x)
     69     {
     70         s[x]=v[x];
     71         for4(i,x)
     72         {
     73             dfs(y);
     74             ans+=(ll)s[x]*s[y]*T.l[x];
     75             s[x]+=s[y];
     76         }
     77         head[x]=0;
     78     }
     79 }G;
     80 inline bool cmp(int x,int y){return T.dfn[x]<T.dfn[y];}
     81 int main()
     82 {
     83     freopen("input.txt","r",stdin);
     84     freopen("output.txt","w",stdout);
     85     n=read();m=read();
     86     T.init();
     87     while(m--)
     88     {
     89         int k=read();
     90         for1(i,k)a[i]=id[read()];
     91         sort(a+1,a+k+1,cmp);
     92         for1(i,k)v[a[i]]=1;
     93         sta[top=1]=1;G.tot=0;
     94         for1(i,k)
     95         {
     96             int x=a[i],f=T.lca(sta[top],x);
     97             while(dep[f]<dep[sta[top]])
     98             {
     99                 if(dep[f]>=dep[sta[top-1]])
    100                 {
    101                     G.add(f,sta[top--]);
    102                     if(sta[top]!=f)sta[++top]=f;
    103                     break;
    104                 }
    105                 G.add(sta[top-1],sta[top]);top--;
    106             }
    107             if(sta[top]!=x)sta[++top]=x;
    108         }
    109         while(--top)G.add(sta[top],sta[top+1]);
    110         ans=0;
    111         G.dfs(1);
    112         printf("%I64d
    ",ans);
    113         for1(i,k)v[a[i]]=0;
    114     }      
    115     return 0;
    116 }
    View Code

    2780: [Spoj]8093 Sevenk Love Oimaster

    给出n个串,在给出m个询问,每次询问一个串s在给出的n个串中多少个串中出现了.

    好像后缀数组也能做?跑出sa,然后二分出左右端点,再上一次 hill的项链?估计也不会好写到哪里去...(就是不知道能不能建出SA)

    还是说SAM做法。

    所谓广义后缀自动机,就是多个串的后缀自动机。具体构建方法为了不存在两个串首尾相接构成新的串的情况,每加入一个串,我们就让last=root。

    然后往下走的时候如果已经有出边了{l[go[last][x]]==l[last]+1那么就直接last=go[last][x],否则新建一个节点balabala。}否则还按原来的来。

    然后因为一个节点有可能属于不同的串。所以我们要在后面挂链表。

    那么我们对每个询问串从root沿着出边走,结束的时候在parent树中它在子树中的任意一个串中都出现了。这样问题就成了多次询问一个区间内有多少个不同的数字了。

    @SDOI2009HH的项链

    第一次感觉自己的代码写的好丑TAT

      1 struct graph
      2 {
      3     int tot,head[maxn];
      4     struct edge{int go,next;}e[maxn];
      5     void add(int x,int y)
      6     {
      7         e[++tot]=(edge){y,head[x]};head[x]=tot;
      8     }
      9 }A,B;
     10 int s[maxn],n,m,pos[maxn];
     11 struct rec{int x,y,id;}a[maxn];
     12 struct sam
     13 {
     14     int cnt,last,l[maxn],id[maxn][2],fa[maxn],ti;
     15     map<int,int>go[maxn];
     16     char s[maxn];
     17     sam(){cnt=1;}
     18     void add(int x,int y)
     19     {
     20         int p=last,q;
     21         if(q=go[p][x])
     22         {
     23             if(l[p]+1==l[q])last=q;
     24             else 
     25             {
     26                 int nq=++cnt;l[nq]=l[p]+1;
     27                 go[nq]=go[q];
     28                 fa[nq]=fa[q];
     29                 fa[q]=nq;
     30                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
     31                 last=nq;
     32             }
     33         }else
     34         {
     35             int np=++cnt;l[np]=l[p]+1;
     36             for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
     37             if(!p)fa[np]=1;
     38             else
     39             {
     40                 q=go[p][x];
     41                 if(l[p]+1==l[q])fa[np]=q;
     42                 else
     43                 {
     44                     int nq=++cnt;l[nq]=l[p]+1;
     45                     go[nq]=go[q];
     46                     fa[nq]=fa[q];
     47                     fa[q]=fa[np]=nq;
     48                     for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
     49                 }
     50             }
     51             last=np;
     52         }
     53         B.add(last,y);//printf("%d %d
    ",last,y);
     54     }
     55     void dfs(int x)
     56     {
     57         id[x][0]=++ti;pos[ti]=x;
     58         for4(A,i,x)dfs(y);
     59         id[x][1]=ti;
     60     }
     61     void insert(int y)
     62     {
     63         last=1;
     64         scanf("%s",s);int n=strlen(s);
     65         for0(i,n-1)add(s[i],y);
     66     }
     67     void work()
     68     {
     69         for1(i,cnt)A.add(fa[i],i);
     70         dfs(1);
     71     }
     72     rec find(int j)
     73     {
     74         scanf("%s",s);int n=strlen(s),now=1;
     75         for0(i,n-1)now=go[now][s[i]];
     76         return now?(rec){id[now][0],id[now][1],j}:(rec){2,1,j};
     77     }
     78 }T;
     79 void update(int x,int y)
     80 {    
     81     //printf("%d %d
    ",x,y);
     82     for(;x<=T.cnt;x+=x&(-x))s[x]+=y;
     83 }
     84 int sum(int x)
     85 {
     86     int t=0; 
     87     for(;x;x-=x&(-x))t+=s[x];
     88     //cout<<x<<' '<<t<<endl;
     89     return t;
     90 }
     91 int v[maxn],ans[maxn];
     92 inline bool cmp(rec a,rec b){return a.y<b.y;}
     93 int main()
     94 {
     95     freopen("input.txt","r",stdin);
     96     freopen("output.txt","w",stdout);
     97     n=read();m=read();
     98     for1(i,n)T.insert(i);
     99     T.work();
    100     for1(i,m)a[i]=T.find(i);
    101     sort(a+1,a+m+1,cmp);
    102     //for1(i,m)cout<<i<<' '<<a[i].x<<' '<<a[i].y<<' '<<a[i].id<<endl;
    103     int now=1;
    104     for1(i,T.cnt)
    105     {
    106         for4(B,j,pos[i])
    107          {
    108             if(v[y])update(v[y],-1);
    109             v[y]=i;
    110             update(v[y],1);
    111          }
    112         //cout<<i<<' '<<a[now].x<<' '<<a[now].y<<' '<<a[now].id<<endl;
    113         while(a[now].y==i)ans[a[now].id]=sum(a[now].y)-sum(a[now].x-1),now++;
    114     }
    115     for1(i,m)printf("%d
    ",ans[i]);    
    116     return 0;
    117 }
    View Code

    3473: 字符串

    给出n个串,问每个串有多少个子串在至少k个串中都出现了。

    类似于上一题,我们可以用“项链”的方法离线求出所有节点所代表的字符串的集合在多少个字符串中出现过。

    如果他的出现次数>=k次,那么他对答案的贡献是l[i]-l[fa[i]]然后一个后缀对答案的总贡献就是他到根节点的权值和。然后再预处理一下就可以了。

    修改了一下代码感觉美观多了

      1 int n,last,cnt=1,ti,k;
      2 typedef int arr[maxn];
      3 arr l,fa,s,f,pos,a,v;
      4 int go[maxn][26],id[maxn][2];
      5 char ch[maxn];
      6 struct graph
      7 {
      8     int tot,head[maxn];
      9     struct edge{int go,next;}e[maxn];
     10     inline void add(int x,int y)
     11     {
     12         e[++tot]=(edge){y,head[x]};head[x]=tot;
     13     }
     14 }A,B,C;
     15 inline void add(int x)
     16 {
     17     int p=last,q;
     18     if(q=go[p][x])
     19     {
     20         if(l[p]+1==l[q])last=q;
     21         else
     22         {
     23             int nq=++cnt;l[nq]=l[p]+1;
     24             memcpy(go[nq],go[q],sizeof(go[q]));
     25             fa[nq]=fa[q];
     26             fa[q]=nq;
     27             for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
     28             last=nq;
     29         }
     30     }else
     31     {
     32         int np=++cnt;l[np]=l[p]+1;
     33         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
     34         if(!p)fa[np]=1;
     35         else
     36         {
     37             q=go[p][x];
     38             if(l[p]+1==l[q])fa[np]=q;
     39             else
     40             {
     41                 int nq=++cnt;l[nq]=l[p]+1;
     42                 memcpy(go[nq],go[q],sizeof(go[q]));
     43                 fa[nq]=fa[q];
     44                    fa[q]=fa[np]=nq;
     45                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
     46             }
     47         }
     48         last=np;
     49     }
     50 }
     51 inline void dfs(int x)
     52 {
     53     id[x][0]=++ti;pos[ti]=x;
     54     for4(C,i,x)dfs(y);
     55     id[x][1]=ti;
     56 }
     57 inline void dfs2(int x)
     58 {
     59     for4(C,i,x)f[y]+=f[x],dfs2(y);
     60 }
     61 inline void update(int x,int y)
     62 {
     63     for(;x<=cnt;x+=x&(-x))s[x]+=y;
     64 }
     65 inline int sum(int x)
     66 {
     67     int t=0;
     68     for(;x;x-=x&(-x))t+=s[x];
     69     return t;
     70 }
     71 inline bool cmp(int x,int y){return id[x][1]<id[y][1];}
     72 int main()
     73 {
     74     freopen("input.txt","r",stdin);
     75     freopen("output.txt","w",stdout);
     76     n=read();k=read();
     77     for1(i,n)
     78     {
     79         last=1;
     80         scanf("%s",ch);int m=strlen(ch);
     81         for0(j,m-1)add(ch[j]-'a'),A.add(last,i),B.add(i,last);
     82     }
     83     for1(i,cnt)C.add(fa[i],i);
     84     dfs(1);
     85     for1(i,cnt)a[i]=i;
     86     sort(a+1,a+cnt+1,cmp);
     87     int now=1;
     88     for1(i,cnt)
     89     {
     90         for4(A,j,pos[i])
     91         {
     92             if(v[y])update(v[y],-1);
     93             v[y]=i;
     94             update(v[y],1);
     95         }    
     96         while(id[a[now]][1]==i)f[a[now]]=(sum(id[a[now]][1])-sum(id[a[now]][0]-1))>=k?l[a[now]]-l[fa[a[now]]]:0,now++;
     97     }
     98     dfs2(1);
     99     for1(i,n)
    100     {
    101         ll ans=0;
    102         for4(B,j,i)ans+=f[y];
    103         printf("%lld",ans);if(i!=n)printf(" ");
    104     }
    105     return 0;
    106 }
    View Code

    3926: [Zjoi2015]诸神眷顾的幻想乡

    [捂脸熊]没想到这题这么简单233 因为叶子很少,所以直接枚举所有的叶子把从他开始dfs顺便建立建立广义自动机,然后求本质不同的字符串的个数。然后就完了。。。

     1 int n,k,tot,cnt,last;
     2 typedef int arr[maxn];
     3 arr fa,l,head,du,a;
     4 int go[maxn][12];
     5 struct edge{int go,next;}e[maxn];
     6 inline void add(int x,int y)
     7 {
     8     e[++tot]=(edge){y,head[x]};head[x]=tot;du[x]++;
     9     e[++tot]=(edge){x,head[y]};head[y]=tot;du[y]++;
    10 }
    11 inline void add(int x)
    12 {
    13     int p=last,q;
    14     if(q=go[p][x])
    15     {
    16         if(l[p]+1==l[q])last=q;
    17         else
    18         {
    19             int nq=++cnt;l[nq]=l[p]+1;
    20             memcpy(go[nq],go[q],sizeof(go[q]));
    21             fa[nq]=fa[q];
    22             fa[q]=nq;
    23             for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
    24             last=nq;
    25         }
    26     }else
    27     {
    28         int np=++cnt;l[np]=l[p]+1;
    29         for(;p&&!go[p][x];p=fa[p])go[p][x]=np;
    30         if(!p)fa[np]=1;
    31         else
    32         {
    33             q=go[p][x];
    34             if(l[p]+1==l[q])fa[np]=q;
    35             else
    36             {
    37                 int nq=++cnt;l[nq]=l[p]+1;
    38                 memcpy(go[nq],go[q],sizeof(go[q]));
    39                 fa[nq]=fa[q];
    40                    fa[q]=fa[np]=nq;
    41                 for(;p&&go[p][x]==q;p=fa[p])go[p][x]=nq;
    42             }
    43         }
    44         last=np;
    45     }
    46 }
    47 inline void dfs(int x,int f,int z)
    48 {
    49     add(a[x]);
    50     int t=last;
    51     for4(i,x)if(y!=f){dfs(y,x,last);last=t;}
    52 }
    53 int main()
    54 {
    55     freopen("input.txt","r",stdin);
    56     freopen("output.txt","w",stdout);
    57     n=read();k=read();
    58     for1(i,n)a[i]=read();
    59     for1(i,n-1)add(read(),read());
    60     cnt=1;
    61     for1(i,n)if(du[i]==1)dfs(i,0,last=1);
    62     ll ans=0;
    63     for1(i,cnt)ans+=l[i]-l[fa[i]];
    64     cout<<ans<<endl;
    65     return 0; 
    66 }
    View Code
  • 相关阅读:
    微信小程序-movable-view
    微信小程序-swiper组件
    大文件上传的php.ini配置和apache或者nginx需要的配置
    Yii2.0 实现关联查询
    Yii2.0关闭自带的debug功能
    创建日志文件,并且追加内容
    微信小程序实现计算器功能
    Yii2.0实现后台接收json数据处理数据修改功能
    Yii2.0成功或者失败提示➕页面跳转
    Yii2.0配置pathinfo模式
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4397216.html
Copyright © 2011-2022 走看看