• 「训练日志18」 (8.16) 认清自己


    前几天的题先鸽了

    T1 mine

      简单$dp$,注意转移意义即可。

      我的定义比较麻烦,可是参考我关注的其他大佬的博客。

      定义$f_{i,j,k}$表示当前位置$i$,当前元素是$j$,上一个元素是$k$的方案数。i维可以滚起来。

      没啥好说的,稍微麻烦点的就是$?$和$1$了,其他的就模拟转移就可以了。

      小弟不才。

      1 #include<cstdio>
      2 #include<string>
      3 #include<iostream>
      4 #include<cstring>
      5 #define LL long long
      6 #define HZOI std
      7 using namespace HZOI;
      8 const int mod=1e9+7;
      9 LL ans;
     10 int n;
     11 char s[1000003],a[1000003];
     12 LL dp[1000003][5][5];
     13 inline void Mod(LL &a) {while (a>=mod) a-=mod;}
     14 int main()
     15 {
     16     char cc=getchar();
     17     while (cc!='0' and cc!='1' and cc!='2' and cc!='*' and cc!='?') cc=getchar();
     18     while (cc=='0' or cc=='1' or cc=='2' or cc=='*' or cc=='?') 
     19     {
     20         if (cc=='?') a[++n]=4;
     21         else if (cc=='*') a[++n]=3;
     22         else a[++n]=cc-48;
     23         cc=getchar();
     24     }
     25     if (a[1]!=4 and a[2]!=4) dp[2][a[2]][a[1]]=1;
     26     if (a[1]==4 and a[2]!=4)
     27     {
     28         if (!a[2])
     29             dp[2][a[2]][0]=1;
     30         if (a[2]==1)
     31             dp[2][a[2]][0]=dp[2][a[2]][3]=1;
     32         if (a[2]==2)
     33             dp[2][a[2]][3]=1;
     34         if (a[2]==3)
     35             dp[2][a[2]][3]=dp[2][a[2]][1]=1;
     36     }
     37     if (a[1]!=4 and a[2]==4)
     38     {
     39         if (!a[1])
     40             dp[2][0][a[1]]=dp[2][1][a[1]]=1;
     41         if (a[1]==1)
     42             dp[2][3][a[1]]=1;
     43         if (a[1]==2) return puts("0"),0;
     44         if (a[1]==3)
     45             dp[2][1][a[1]]=dp[2][2][a[1]]=dp[2][3][a[1]]=1;
     46     }
     47     if (a[1]==4 and a[2]==4)
     48     {
     49         dp[2][0][0]=dp[2][1][0]=dp[2][3][1]=dp[2][1][3]=dp[2][2][3]=dp[2][3][3]=1;
     50     }
     51     for (int i=3; i<=n; ++i)
     52     {
     53         if (!a[i])
     54             for (int j=0; j<3; ++j)
     55             {
     56                 if (!j)
     57                     for (int k=0; k<2; ++k)
     58                         Mod(dp[i][0][j]+=dp[i-1][j][k]);
     59                 if (j==1)
     60                     Mod(dp[i][0][j]+=dp[i-1][j][3]);
     61             }
     62         if (a[i]==1)
     63             for (int j=0; j<4; ++j)
     64             {
     65                 if (!j)
     66                     for (int k=0; k<2; ++k)
     67                         Mod(dp[i][1][j]+=dp[i-1][j][k]);
     68                 if (j==1)
     69                     Mod(dp[i][1][j]+=dp[i-1][j][3]);
     70                 if (j==3)
     71                     for (int k=1; k<4; ++k)
     72                         Mod(dp[i][1][j]+=dp[i-1][j][k]);
     73             }    
     74         if (a[i]==2)
     75             for (int j=1; j<4; ++j)
     76                 Mod(dp[i][2][3]+=dp[i-1][3][j]);
     77         if (a[i]==3)
     78             for (int j=1; j<4; ++j)
     79             {
     80                 if (j==1)
     81                     for (int k=0; k<2; ++k)
     82                         Mod(dp[i][3][j]+=dp[i-1][j][k]);
     83                 if (j==2)
     84                     Mod(dp[i][3][j]+=dp[i-1][j][3]);
     85                 if (j==3)
     86                     for (int k=1; k<4; ++k)
     87                         Mod(dp[i][3][j]+=dp[i-1][j][k]);
     88             }
     89         if (a[i]==4)
     90             for (int g=0; g<4; ++g)
     91             {
     92                 if (!g)
     93                     for (int j=0; j<3; ++j)
     94                     {
     95                         if (!j)
     96                             for (int k=0; k<2; ++k)
     97                                 Mod(dp[i][0][j]+=dp[i-1][j][k]);
     98                         if (j==1)
     99                             Mod(dp[i][0][j]+=dp[i-1][j][3]);
    100                     }
    101                 if (g==1)
    102                     for (int j=0; j<4; ++j)
    103                     {
    104                         if (!j)
    105                             for (int k=0; k<2; ++k)
    106                                 Mod(dp[i][1][j]+=dp[i-1][j][k]);
    107                         if (j==1)
    108                             Mod(dp[i][1][j]+=dp[i-1][j][3]);
    109                         if (j==3)
    110                             for (int k=1; k<4; ++k)
    111                                 Mod(dp[i][1][j]+=dp[i-1][j][k]);
    112                     }    
    113                 if (g==2)
    114                     for (int j=1; j<4; ++j)
    115                         Mod(dp[i][2][3]+=dp[i-1][3][j]);
    116                 if (g==3)
    117                     for (int j=1; j<4; ++j)
    118                     {
    119                         if (j==1)
    120                             for (int k=0; k<2; ++k)
    121                                 Mod(dp[i][3][j]+=dp[i-1][j][k]);
    122                         if (j==2)
    123                             Mod(dp[i][3][j]+=dp[i-1][j][3]);
    124                         if (j==3)
    125                             for (int k=1; k<4; ++k)
    126                                 Mod(dp[i][3][j]+=dp[i-1][j][k]);
    127                     }
    128             }
    129     }
    130     Mod(ans+=dp[n][0][0]+dp[n][0][1]+dp[n][1][3]+dp[n][3][1]+dp[n][3][2]+dp[n][3][3]);
    131     printf("%lld
    ",(ans+mod)%mod);
    132 }
    mine

    T2 water

      考试的时候没有深入理解题意,导致蒙到了$20$分。

      其实思路也不难,但是考试的时候真没想到。

      这道题主要是一个思路,要从边界开始向里扫,用边界的状态更新内部状态,找到一个最低的可以流出去的口,这是这道题的关键。

      我们可以考虑$SPFA$遍历整张图,然后不断用dis值更新它的答案,要注意不能之考虑起点的$dis$,也要考虑终点的$a$值,两者取$max$,因为我一定要保证答案不能出现“倒流”的情况。

      小弟不才。

      

     1 #include<cstdio>
     2 #include<cstring>
     3 #define LL long long
     4 #define HZOI std
     5 using namespace HZOI;
     6 int n,m;
     7 LL head,tail,a[303][303],dis[303][303],vis[303][303],quei[1000003],quej[1000003];
     8 int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
     9 inline void Bfs();
    10 inline LL read();
    11 inline LL max(LL a,LL b) {return a>b?a:b;}
    12 inline LL min(LL a,LL b) {return a<b?a:b;}
    13 int main()
    14 {
    15     n=read(),m=read();
    16     for (int i=1; i<=n; ++i)
    17         for (int j=1; j<=m; ++j)
    18             a[i][j]=read();
    19     memset(dis,0x3f,sizeof(dis));
    20     head=tail=0;
    21     for (int i=1; i<=n; ++i)
    22     {
    23         dis[i][m]=max(0,a[i][m]);
    24         dis[i][1]=max(0,a[i][1]);
    25         if (!vis[i][m]) quei[++tail]=i, quej[tail]=m, vis[i][m]=1;
    26         if (!vis[i][1]) quei[++tail]=i, quej[tail]=1, vis[i][1]=1;
    27     }
    28     for (int i=1; i<=m; ++i)
    29     {
    30         dis[n][i]=max(0,a[n][i]);
    31         dis[1][i]=max(0,a[1][i]);
    32         if (!vis[n][i]) quei[++tail]=n, quej[tail]=i, vis[n][i]=1;
    33         if (!vis[1][i]) quei[++tail]=1, quej[tail]=i, vis[1][i]=1;
    34     }
    35     Bfs();
    36     for (int i=1; i<=n; ++i)
    37     {
    38         for (int j=1; j<=m; ++j)
    39             printf("%lld ",dis[i][j]-a[i][j]);
    40         puts("");
    41     }
    42 }
    43 inline void Bfs()
    44 {
    45     while (head^tail)
    46     {
    47         int xi=quei[++head],xj=quej[head];
    48         vis[xi][xj]=0;
    49         for (int i=0; i<4; ++i)
    50         {
    51             int toi=xi+dx[i],toj=xj+dy[i];
    52             if (toi>0 and toi<=n and toj>0 and toj<=m)
    53             {
    54                 int dtc=max(a[toi][toj],dis[xi][xj]);
    55                 if (dis[toi][toj]>dtc)
    56                 {
    57                     dis[toi][toj]=dtc;
    58                     if (!vis[toi][toj]) quei[++tail]=toi,quej[tail]=toj,vis[toi][toj]=1;
    59                 }
    60             }
    61         }
    62     }
    63 }
    64 inline LL read()
    65 {
    66     LL nn=0,ff=1; char cc=getchar();
    67     while (cc<'0' or cc>'9') {if (cc=='-') ff=-1; cc=getchar();}
    68     while (cc>='0' and cc<='9') nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar();
    69     return nn*ff;
    70 }
    water

    T3 gcd

      数学题,在我看来又是一道神仙题。

      互质:最大公约数为$1$。

      然后我们发现它其实跟本身的$x$没有太大关系,只与它能分解成的约数有关,因此便可以想到一个思路:把所有数都分解成约数,然后乱搞。

      但是约数仍然很大,我们不可能枚举所有的约数来进行计算,所以我们还要继续分解。将他们的约数继续分解成若干个质数乘积的形式,记录每个约数都是这个质数的几倍,然后用一个组合数$C_n^2$转移到公约数为i的倍数的点对数,最后莫比乌斯反演求出最大公约数为1的点对数。

      定义三个数组$s$,$g$,$f$,分别代表上述含义,每次只需要枚举要操作的数的所有的约数,给$s$加或减,就可以维护到$g$,进而计算$f$的值。

      复杂度$O(msqrt(max(a)))$。

      注意a值可能会重复,$vis$要记录操作位置。

      小弟不才。

      

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<vector>
     4 #include<cstring>
     5 #define LL long long
     6 #define HZOI std
     7 using namespace HZOI;
     8 const LL N=2e5+3;
     9 const LL X=5e5+3;
    10 LL n,m,maxa;
    11 LL tot,a[N];
    12 LL f,g[X],s[X];
    13 LL cnt,mu[X],vis[X],prime[X];
    14 vector<LL> ys[X];
    15 inline void Add(LL ,LL );
    16 inline void Init();
    17 inline LL read();
    18 inline LL max(LL a,LL b) {return a>b?a:b;}
    19 inline LL min(LL a,LL b) {return a<b?a:b;}
    20 int main()
    21 {
    22     LL flag=0;
    23     n=read(),m=read();
    24     for (int i=1; i<=n; ++i)
    25         a[i]=read(),maxa=max(a[i],maxa);
    26     Init();
    27     memset(vis,0,sizeof(vis));
    28     for (int i=1,x; i<=m; ++i)
    29     {
    30         x=read();
    31         if (!vis[x])
    32         {
    33             Add(a[x],1);
    34             printf("%lld
    ",f);
    35             vis[x]=1;
    36         }
    37         else 
    38         {
    39             vis[x]=0;
    40             Add(a[x],-1);
    41             printf("%lld
    ",f);
    42         }
    43     }
    44     return 0;
    45 }
    46 inline void Add(LL x,LL data)
    47 {
    48     int len=ys[x].size();
    49     for (int i=0; i<len; ++i)
    50     {
    51         LL jsx=ys[x][i];
    52         s[jsx]+=data;
    53         f-=g[jsx]*mu[jsx];
    54         g[jsx]=s[jsx]*(s[jsx]-1)/2;
    55         f+=g[jsx]*mu[jsx];
    56     }
    57 }
    58 inline void Init()
    59 {
    60     mu[1]=1;
    61     cnt=0;
    62     memset(vis,0,sizeof(vis));
    63     for (int i=2; i<=maxa; ++i)
    64     {
    65         if (!vis[i])
    66             prime[++cnt]=i,vis[i]=1,mu[i]=-1;
    67         for (int j=1; j<=cnt && i*prime[j]<=maxa; ++j)
    68         {
    69             vis[i*prime[j]]=1;
    70             if (i%prime[j]) mu[i*prime[j]]=-mu[i];
    71             else {mu[i*prime[j]]=0;break;}
    72         }
    73     }
    74     for (int i=1; i<=maxa; ++i)
    75         for (int j=1; j*i<=maxa; ++j)
    76             ys[i*j].push_back(i);
    77 }
    78 inline LL read()
    79 {
    80     LL nn=0; char cc=getchar();
    81     while (cc<'0' or cc>'9') cc=getchar();
    82     while (cc>='0' and cc<='9') nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar();
    83     return nn;
    84 }
    gcd
  • 相关阅读:
    斯托克斯定理(Stokes' theorem)
    记号的认识、公式的理解
    记号的认识、公式的理解
    Python 金融数据分析 (一)—— 股票数据
    Python 金融数据分析 (一)—— 股票数据
    开源项目
    开源项目
    感知机模型及其对偶形式
    感知机模型及其对偶形式
    jni编译non-numeric second argument to `wordlist' function错误
  • 原文地址:https://www.cnblogs.com/LH-Xuanluo/p/11366524.html
Copyright © 2020-2023  润新知