• cf 1105 C. Ayoub and Lost Array(dp)


    这道题如果考虑从头到位枚举每一位每次只用考虑3*3种转移方式,于是题目重点就变成了如何找到L到R区间内%3后余数是1,2,3的数字各有多少个

    我一开始是直接模拟的

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll now[3];
    ll dp[200010][3];
    const int MOD=1e9+7;
    int main()
    {
        int n,l,r;
        scanf("%d%d%d",&n,&l,&r);
        if(r-l+1<3&&r!=l)
           now[l%3]++,now[r%3]++;
        else if(r==l)
           now[l%3]++;
        else
        {
        int tmpl,tmpr;
        if(l%3==0)
           tmpl=l,now[0]++;
        else if(l%3==1)
           tmpl=l+2,now[1]++,now[0]++,now[2]++;
        else if(l%3==2)
           tmpl=l+1,now[2]++,now[0]++;
        if(r%3==0)
           tmpr=r;
        else if(r%3==1)
           tmpr=r-1,now[1]++;
        else if(r%3==2)
           tmpr=r-2,now[1]++,now[2]++;
        if(tmpl<tmpr)
        {
            for(int i=0;i<=2;i++)
               now[i]+=(tmpr-tmpl)/3;
        }
        }
        dp[1][0]=now[0];
        dp[1][1]=now[1];
        dp[1][2]=now[2];
        for(int i=2;i<=n;i++)
        {
            for(int j=0;j<=2;j++)
            {
                for(int k=0;k<=2;k++)
                {
                    dp[i][(j+k)%3]+=dp[i-1][j]*now[k];
                    dp[i][(j+k)%3]%=MOD;
                }
            }
        }
        printf("%lld
    ",dp[n][0]);
    }

    但是之后发现了个更好的方法,就是如果考虑余数为一的时候,把所有数字同一加上2;考虑余数为2的时候同一加上一,这样就相当于在新的区间内找有多少个可以整除3的数字

    int c0 = (r/3 - (l-1)/3) % mod;
    int c1 = ((r+2)/3 - (l+1)/3)%mod;
    int c2 = ((r+1)/3 - (l)/3)%mod;

    还可以解不等式来做比如说要找余数为一的数字  l≤3k+1≤r, l13kr1,ceil( (l−1)/3 )≤k≤floor( (r−1)/3 ).

  • 相关阅读:
    多项式学习笔记(二) NTT
    矩阵树定理学习笔记
    拓展BSGS 学习笔记
    P2257 YY的GCD
    P1891 疯狂的lcm
    友链
    关于我
    焚燃指间の回忆
    洛谷P4180
    洛谷P2292
  • 原文地址:https://www.cnblogs.com/lishengkangshidatiancai/p/10298452.html
Copyright © 2020-2023  润新知