AtCoder Beginner Contest 129

ABCD

签到(ABC过水已隐藏)

#include<bits/stdc++.h>
using namespace std;
const int N=2003;
int n,m,ans,f1[N][N],f2[N][N],f3[N][N],f4[N][N];
char mp[N][N];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(mp[i][j]=='.')f1[i][j]=f1[i-1][j]+1,f2[i][j]=f2[i][j-1]+1;
    for(int i=n;i;i--)
    for(int j=m;j;j--)
    if(mp[i][j]=='.')f3[i][j]=f3[i+1][j]+1,f4[i][j]=f4[i][j+1]+1;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(mp[i][j]=='.')ans=max(ans,f1[i][j]+f2[i][j]+f3[i][j]+f4[i][j]-3);
    printf("%d\n",ans);
}
View Code

E

发现x^y=x+y时,x,y没有同时为1的位。于是数位DP,f[i][0/1]表示到了第i位是否达到上限,发现该位取1有2种方案,取0有1种,大力O(n)DP即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7,mod=1e9+7;
int n,ans,f[N][2];
char s[N];
int main()
{
    scanf("%s",s+1);
    n=strlen(s+1);
    f[0][1]=1;
    for(int i=1;i<=n;i++)
    if(s[i]=='1')f[i][0]=(3ll*f[i-1][0]+f[i-1][1])%mod,f[i][1]=2ll*f[i-1][1]%mod;
    else f[i][0]=3ll*f[i-1][0]%mod,f[i][1]=f[i-1][1];
    ans=(f[n][0]+f[n][1])%mod;
    printf("%d",ans);
}
View Code

F

设计算到x时,答案是ans,于是计算x后,ans=(ans*10i+x)%m,其中i为x的位数,然后发现这个可以矩阵转移,对于位数相同的数字,转移的矩阵是相同的,于是分位数转移至多18次即可,复杂度O(27logBLlgBL)。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll L,st,ed,b,pw[19];
int m,ans;
struct mat{
    int a[3][3];
    mat(){memset(a,0,sizeof a);}
    void init(int i)
    {
        memset(a,0,sizeof a);
        a[0][0]=pw[i]%m,a[1][0]=a[1][1]=a[2][1]=a[2][2]=1;
    }
}A,ret;
mat operator*(mat a,mat b)
{
    mat c;
    for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
    for(int k=0;k<3;k++)
    c.a[i][j]=(c.a[i][j]+1ll*a.a[i][k]*b.a[k][j])%m;
    return c;
}
int solve(ll L,ll R,int id)
{
    ll n=(R-L)/b+1;
    for(int i=0;i<3;i++)for(int j=0;j<3;j++)ret.a[i][j]=i==j;
    A.init(id);
    while(n)
    {
        if(n&1)ret=ret*A;
        A=A*A,n>>=1;
    }
    ans=(1ll*ans*ret.a[0][0]+L%m*ret.a[1][0]+b%m*ret.a[2][0])%m;
}
int main()
{
    pw[0]=1;for(int i=1;i<=18;i++)pw[i]=pw[i-1]*10;
    cin>>L>>st>>b>>m;
    ed=st+b*(L-1);
    for(int i=1;i<=18;i++)
    if(st<pw[i])
    {
        ll R=(pw[i]-1-st)/b*b+st;
        if(R>ed)R=ed;
        solve(st,R,i);
        if(R==ed)break;
        st=R+b;
    }
    cout<<ans<<endl;
}
View Code

result:rank5 rating+=65 now_rating=2020,ABC为什么performance上限要设2400?就涨了这么点……不过好在上黄了。

猜你喜欢

转载自www.cnblogs.com/hfctf0210/p/10995140.html