zoukankan      html  css  js  c++  java
  • codeforces edu40

    H(dp计数)

    题意:

      有一颗树,最深的点的深度是n,每个深度为i的点都有ai个孩子。

      对于1<=k<=2n-2,回答树上有多少点对之间的距离是k,答案对1e9+7取模

      n<=5000,ai<=1e9

    分析:

      考虑在lca处计数,发现时间复杂度是O(n^3),即使用卷积优化也仍旧是O(n^2logn)的,无法通过n=5000的情况

      考虑另一种计数方式,在端点处计数,分为两种,一种是down,一种是up,down就比较好处理,至于up考虑根据上一个深度来dp

      考虑up的时候只有两种决策,一种是挂一个下来,另一种是在当前深度的上一个进行转弯,分别计数即可

      时间复杂度O(n^2)

    G(FFT+dsu)

    题意:

      我们定义两个等长字符串x和y的距离就是将最少的字母让另一种字母替代,使得x=y

      现在给出两个字符串S,T,|S|>=|T|,问S的所有长度为T的子串,每个子串和T的距离分别是多少,都要输出

      |S|<=125000

      字符集只有abcdef

    分析:

      考虑如何求两个等长字符串的距离,我们只需要给对应字母建个无向图,答案就是点数-连通块个数

      因为字符集很小,只有abcdef,所以连边情况只有36种,可以状态压缩

      我们可以枚举s中的某个字母a,t中的某个字母b,看看有哪些位置的S子串会被这个(a,b)贡献到

      这个东西可以用卷积来实现

      把s中a的对应位置抠出来赋值为1,其它为0,把t中b的对应位置抠出来赋值为1,其它为0,两个多项式卷积一下就行了

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=5e5;
      4 const double pi=acos(-1.0);
      5 char t[maxn+5],s[maxn+5];
      6 int id[6][6];
      7 pair<int,int> index[36];
      8 long long state[maxn+5];
      9 int n,m;
     10 struct wjmzbmr
     11 {
     12     double r,i;
     13     wjmzbmr(double real=0.0,double image=0.0){r=real;i=image;}
     14     wjmzbmr operator + (const wjmzbmr o)
     15     {
     16         return wjmzbmr(r+o.r,i+o.i);
     17     }
     18     wjmzbmr operator - (const wjmzbmr o)
     19     {
     20         return wjmzbmr(r-o.r,i-o.i);
     21     }
     22     wjmzbmr operator * (const wjmzbmr o)
     23     {
     24         return wjmzbmr(r*o.r-i*o.i,r*o.i+i*o.r);
     25     }
     26 };
     27 wjmzbmr x1[maxn+5],x2[maxn+5];
     28 void brc(wjmzbmr *y,int l)
     29 {
     30     for(int i=1,j=l/2;i<l-1;i++)
     31     {
     32         if(i<j) swap(y[i],y[j]);
     33         int k=l/2;
     34         while(j>=k)j-=k,k/=2;
     35         if(j<k) j+=k;
     36     }
     37 }
     38 void fft(wjmzbmr *y,int l,double on)
     39 {
     40     wjmzbmr u,t;
     41     brc(y,l);
     42     for(int h=2;h<=l;h<<=1)
     43     {
     44         wjmzbmr wn(cos(on*2*pi/h),sin(on*2*pi/h));
     45         for(int j=0;j<l;j+=h)
     46         {
     47             wjmzbmr w(1,0);
     48             for(int k=j;k<j+h/2;k++)
     49             {
     50                 u=y[k];
     51                 t=w*y[k+h/2];
     52                 y[k]=u+t;
     53                 y[k+h/2]=u-t;
     54                 w=w*wn;
     55             }
     56         }
     57     }
     58     if(on==-1)for(int i=0;i<l;i++) y[i].r/=l;
     59 }
     60 void work(int x,int y)
     61 {
     62     int len=1;
     63     while(len<n+m) len<<=1;
     64     for(int i=0;i<=len;++i) x1[i].r=x1[i].i=x2[i].i=x2[i].r=0.0;
     65     for(int i=0;i<n;++i) if(s[i]==x+'a') x1[i].r=1;
     66     for(int i=0;i<m;++i) if(t[i]==y+'a') x2[i].r=1;
     67     reverse(x2,x2+m);
     68     fft(x1,len,1);
     69     fft(x2,len,1);
     70     for(int i=0;i<len;++i) x1[i]=x1[i]*x2[i];
     71     fft(x1,len,-1);
     72     for(int i=0;i<n;++i)
     73         if((int)(x1[i+m-1].r+0.5)>0) state[i]|=(1LL<<id[x][y]);
     74 }
     75 int f[6];
     76 int find(int x)
     77 {
     78     if(f[x]==x) return x;
     79     else return f[x]=find(f[x]);
     80 }
     81 void uni(int x,int y)
     82 {
     83     int u=find(x),v=find(y);
     84     if(u==v) return ;
     85     f[u]=v;
     86 }
     87 int cal(long long s)
     88 {
     89     for(int i=0;i<6;++i) f[i]=i;
     90     for(int i=0;i<36;++i)
     91         if(s&(1LL<<i))
     92         {
     93             int u=index[i].first,v=index[i].second;
     94             uni(u,v);
     95         }
     96     int ans=6;
     97     for(int i=0;i<6;++i)
     98         if(f[i]==i) --ans;
     99     return ans;
    100 }
    101 int main()
    102 {
    103     scanf("%s%s",s,t);
    104     n=strlen(s),m=strlen(t);
    105     int sz=0;
    106     for(int i=0;i<6;++i)
    107         for(int j=0;j<6;++j)
    108         {
    109             id[i][j]=sz;
    110             index[sz]=make_pair(i,j);
    111             ++sz;
    112         }
    113     for(int i=0;i<6;++i)
    114         for(int j=0;j<6;++j)
    115             if(i!=j)
    116             work(i,j);
    117     for(int i=0;i<=n-m;++i)
    118         printf("%d ",cal(state[i]));
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    会话追踪技术
    request session application
    Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。
    mysql连接拍错总结
    git 从分支上创建一个分支
    linux ---> taskkill pid 8080 /f
    阿里java开发规范 强制约束
    for break
    Mybatis Update操作返回值问题
    springboot 缓存架构
  • 原文地址:https://www.cnblogs.com/wmrv587/p/8671968.html
Copyright © 2011-2022 走看看