【NOIP2014八校联考第1场第2试】大水题(water)

20 篇文章 0 订阅

Description

dzy 定义一个n^2 位的数的生成矩阵A 为一个大小为n*n 且Aij 为这个数的第i*n+j-n位的矩阵。
现在dzy 有一个数n^2 位的数k,他想知道所有小于等于k 的数的n*n 生成矩阵有多少种。(如果不足n^2 位则补前缀零)

Solution

首先要发现一个性质,除去回文数,其他数字反过来只要不超过k,就一定要减去另一个,于是就有递推式。除以2是因为这样子计算会重复一次。设出 fi,0..1,0..1 表示当前dp做到了第i位;第二维的0表示1..i位的数字与原串的相同,1为不同;第三维的1表示反过来比后i位大,0为小于等于。转移方程随便推一下就可以了。

Code

const mo=1000000007;
var
    a:array[0..1000000] of longint;
    f:array[0..1000000,0..1,0..1] of longint;
    n,k,i,j,sum,mx:longint;
    c:char;
    ans,a1,a2:int64;
function p1(x,y:longint):longint;
begin
    if x=y then exit(1);exit(0);
end;
function p2(x,y:longint):longint;
begin
    if x>y then exit(1);exit(0);
end;
function p3(x,y:longint):longint;
begin
    if x<y then exit(0);exit(1);
end;
begin
    readln(n);
    for i:=1 to n*n do
    begin
        read(c);a[i]:=ord(c)-48;
        mx:=(mx*10+a[i])mod mo;
    end;
    f[0,1,0]:=1;
    n:=n*n;
    for i:=0 to n-1 do
    begin
        for k:=0 to 9 do
        begin
            f[i+1,0,p2(k,a[n-i])]:=(f[i+1,0,p2(k,a[n-i])]+f[i,0,0])mod mo;
            f[i+1,0,p3(k,a[n-i])]:=(f[i+1,0,p3(k,a[n-i])]+f[i,0,1])mod mo;
        end;
        for k:=0 to a[i+1] do
        begin
            f[i+1,p1(k,a[i+1]),p2(k,a[n-i])]:=(f[i+1,p1(k,a[i+1]),p2(k,a[n-i])]+f[i,1,0])mod mo;
            f[i+1,p1(k,a[i+1]),p3(k,a[n-i])]:=(f[i+1,p1(k,a[i+1]),p3(k,a[n-i])]+f[i,1,1])mod mo;
        end;
    end;
    a1:=(f[n,0,0]+f[n,1,0])mod mo;a2:=(f[n div 2,0,0]+f[n div 2,0,1]+f[n div 2,1,0])mod mo;
    ans:=(mx-(a1-a2)*500000004 mod mo+mo)mod mo;
    writeln(ans);
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值