Codechef April Challenge 2018 Division 1 S Semi-palindromic

Semi-palindromic

Description

对于一个不含前导 0 0 的十进制非负整数,如果它是m的倍数,且出现次数为奇数的某个数字最多只有一个(前导 0 0 不算),那么称它是牛逼数。
给定m,n ,求小于 10n 10 n 的牛逼数有多少个,输出答案模 109+7 10 9 + 7

Data Constraints

1m16 1 ≤ m ≤ 16    1n1018       1 ≤ n ≤ 10 18

Solution

这是我打过的为数不多的 FWT F W T 题了。
先考虑一个 O(210nm) O ( 2 10 n m ) 的做法,设 fi,j,S f i , j , S 表示构造至i位,前 i i 位模m j j ,每个数字出现次数的奇偶性的二进制状态为S的方案数,转移很简单,统计答案也很简单。

但这样做显然会超时。
我们再设一个 fl,r,j,S f l , r , j , S 表示构造完第 l l ~r位,第 l l ~r位模 m m j,每个数字出现次数的奇偶性的二进制状态为 S S 的方案数,假设我们已经知道了f1,i,j,S,那我们是可以快速求出 f1+i,2i,j,S f 1 + i , 2 i , j , S ,具体转移为 f1,i,j,S f 1 , i , j , S 可转移到 fi+1,2i, j10i % m,S f i + 1 , 2 i ,   j ∗ 10 i   %   m , S ,然后 f1,i f 1 , i fi+1,2i f i + 1 , 2 i 进行分层异或卷积,就可以得到 f1,2i f 1 , 2 i ,利用这个思想就可以倍增的求了,异或卷积的实现用 FWT F W T

但要注意到一个地方,两个 f f 卷积的时候,前导0将有可能改变 0 0 的个数的奇偶性,因此直接这么做是行不通的。
对此,我们可以设f g g 分别表示有奇数/偶数个前导0时的 dp d p 数组,这样就可以了。

时间复杂度 O(10m 210log n) O ( 10 m   2 10 l o g   n )

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define fo(i,j,l) for(int i=j;i<=l;++i)
#define fd(i,j,l) for(int i=j;i>=l;--i)

using namespace std;
typedef long long ll;
const ll N=1025,M=25,mo=1e9+7,OP=(mo+1)>>1,mm=1023;

ll f[M][N],g[M][N],k1[M][N],k2[M][N],f1[M][N],g1[M][N];
ll v1[M][N],v2[M][N];

int ok[N];
ll w[N];
ll n;
int m,T;

inline ll ksm(ll o,ll t,ll mmm)
{
    ll y=1;
    for(;t;t>>=1,o=o*o%mmm)
    if(t&1)y=y*o%mmm;
    return y;
}

inline ll mo1(ll p)
{return p<mo?p:(p-mo);}

void dft(int a)
{
    for(int m=2;m<=mm+1;m<<=1){
        ll keep;
        register int half=m>>1;
        for(int i=0;i<=mm;i+=m)
        fo(j,0,half-1){
            keep=f[a][i+half+j];
            f[a][i+half+j]=mo1(f[a][j+i]-keep+mo);
            f[a][i+j]=mo1(keep+f[a][i+j]);
        }
    }
    for(int m=2;m<=mm+1;m<<=1){
        ll keep;
        int half=m>>1;
        for(int i=0;i<=mm;i+=m)
        fo(j,0,half-1){
            keep=g[a][i+half+j];
            g[a][i+half+j]=mo1(g[a][j+i]-keep+mo);
            g[a][i+j]=mo1(keep+g[a][i+j]);
        }
    }
    for(int m=2;m<=mm+1;m<<=1){
        ll keep;
        int half=m>>1;
        for(int i=0;i<=mm;i+=m)
        fo(j,0,half-1){
            keep=f1[a][i+half+j];
            f1[a][i+half+j]=mo1(f1[a][j+i]-keep+mo);
            f1[a][i+j]=mo1(keep+f1[a][i+j]);
        }
    }
    for(int m=2;m<=mm+1;m<<=1){
        ll keep;
        int half=m>>1;
        for(int i=0;i<=mm;i+=m)
        fo(j,0,half-1){
            keep=g1[a][i+half+j];
            g1[a][i+half+j]=mo1(g1[a][j+i]-keep+mo);
            g1[a][i+j]=mo1(keep+g1[a][i+j]);
        }
    }
}

void idft(int a)
{
    for(int m=2;m<=mm+1;m<<=1){
        ll keep;
        int half=m>>1;
        for(int i=0;i<=mm;i+=m)
        fo(j,0,half-1){
            keep=v1[a][i+half+j];
            v1[a][i+half+j]=(v1[a][i+j]-keep+mo)*OP%mo;
            v1[a][i+j]=(keep+v1[a][i+j])*OP%mo;
        }
    }
    for(int m=2;m<=mm+1;m<<=1){
        ll keep;
        int half=m>>1;
        for(int i=0;i<=mm;i+=m)
        fo(j,0,half-1){
            keep=v2[a][i+half+j];
            v2[a][i+half+j]=(v2[a][i+j]-keep+mo)*OP%mo;
            v2[a][i+j]=(keep+v2[a][i+j])*OP%mo;
        }
    }
}

void solve(ll o)
{
    w[0]=0;
    for(;o;o>>=1)w[++w[0]]=o;
    fo(i,0,m-1)fo(l,0,mm)f[i][l]=g[i][l]=0;
    fo(i,1,9)f[i%m][ok[i]]=1;
    fd(ko,w[0]-1,1){
        fo(i,0,m-1)fo(l,0,mm)k1[i][l]=f[i][l],f1[i][l]=0;
        fo(i,0,m-1)fo(l,0,mm)k2[i][l]=g[i][l],g1[i][l]=0;
        if(w[ko+1]&1)
        fo(i,0,m-1)fo(l,0,mm)swap(k1[i][l],k2[i][l]);
        int yu=ksm(10,w[ko+1],m);
        fo(i,0,m-1)
        {
            int e=i*yu%m; int u=w[ko+1]&1;
            fo(l,0,mm)f1[e][l]=mo1(f1[e][l]+f[i][l]),k1[e][l^u]=mo1(k1[e][l^u]+f[i][l]);
            fo(l,0,mm)g1[e][l]=mo1(g1[e][l]+g[i][l]),k2[e][l^u]=mo1(k2[e][l^u]+g[i][l]);
        }
        fo(i,0,m-1)fo(l,0,mm)v1[i][l]=v2[i][l]=0;
        fo(i,0,m-1)
        fo(l,0,mm)if(l&1)swap(g[i][l^1],g[i][l]);
        fo(i,0,m-1)dft(i);
        fo(i,0,m-1)fo(j,0,m-1){
            int k=(i+j)%m;
            fo(l,0,mm)v1[k][l]=(v1[k][l]+f1[i][l]*(f[j][l]+g[j][l]))%mo;
            fo(l,0,mm)v2[k][l]=(v2[k][l]+g1[i][l]*(f[j][l]+g[j][l]))%mo;
        }
        fo(i,0,m-1)idft(i);
        fo(i,0,m-1)fo(l,0,mm)f[i][l]=mo1(v1[i][l]+k1[i][l]),g[i][l]=mo1(v2[i][l]+k2[i][l]);
        if(w[ko]&1)
        {
            int e=yu*yu%m;
            fo(i,0,m-1)fo(l,0,mm)v1[i][l]=g[i][l],v2[i][l]=f[i][l];
            fo(j,1,9)
            fo(i,0,m-1){
                int k=(i+j*e)%m;
                fo(l,0,mm)v1[k][l^ok[j]]=(v1[k][l^ok[j]]+f[i][l])%mo;
                fo(l,0,mm)v1[k][l^ok[j]^1]=(v1[k][l^ok[j]^1]+g[i][l])%mo;
            }
            fo(j,1,9)v1[j*e%m][ok[j]^(w[ko]&1)^1]++;
            fo(i,0,m-1)fo(l,0,mm)f[i][l]=v1[i][l],g[i][l]=v2[i][l];
        }
    }
}

int main()
{
    cin>>T;
    ok[0]=1;
    fo(i,1,9)ok[i]=ok[i-1]<<1;
    fo(tt,1,T){
        cin>>m>>n;
        solve(n);
        ll ans=f[0][0]+f[0][1]+1;
        fo(i,1,9)ans=(ans+f[0][ok[i]])%mo;
        ans=ans+g[0][0]+g[0][1];
        fo(i,1,9)ans=(ans+g[0][ok[i]])%mo;
        ans=ans%mo;
        cout<<ans<<endl;
    }
} 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园信息化系统解决方案旨在通过先进的信息技术,实现教育的全方位创新和优质资源的普及共享。该方案依据国家和地方政策背景,如教育部《教育信息化“十三五”规划》和《教育信息化十年发展规划》,以信息技术的革命性影响为指导,推进教育信息化建设,实现教育思想和方法的创新。 技术发展为智慧校园建设提供了强有力的支撑。方案涵盖了互连互通、优质资源共享、宽带网络、移动APP、电子书包、电子教学白板、3D打印、VR虚拟教学等技术应用,以及大数据和云计算技术,提升了教学数据记录和分析水平。此外,教育资源公共服务平台、教育管理公共服务平台等平台建设,进一步提高了教学、管控的效率。 智慧校园系统由智慧教学、智慧管控和智慧办公三大部分组成,各自具有丰富的应用场景。智慧教学包括微课、公开课、精品课等教学资源的整合和共享,支持在线编辑、录播资源、教学分析等功能。智慧管控则通过平安校园、可视对讲、紧急求助、视频监控等手段,保障校园安全。智慧办公则利用远程视讯、无纸化会议、数字会议等技术,提高行政效率和会议质量。 教育录播系统作为智慧校园的重要组成部分,提供了一套满足学校和教育局需求的解决方案。它包括标准课室、微格课室、精品课室等,通过自动五机位方案、高保真音频采集、一键式录课等功能,实现了优质教学资源的录制和共享。此外,录播系统还包括互动教学、录播班班通、教育中控、校园广播等应用,促进了教育资源的均衡化发展。 智慧办公的另一重点是无纸化会议和数字会议系统的建设,它们通过高效的文件管理、会议文件保密处理、本地会议的音频传输和摄像跟踪等功能,实现了会议的高效化和集中管控。这些系统不仅提高了会议的效率和质量,还通过一键管控、无线管控等设计,简化了操作流程,使得会议更加便捷和环保。 总之,智慧校园信息化系统解决方案通过整合先进的信息技术和教学资源,不仅提升了教育质量和管理效率,还为实现教育均衡化和资源共享提供了有力支持,推动了教育现代化的进程。
智慧校园信息化系统解决方案旨在通过先进的信息技术,实现教育的全方位创新和优质资源的普及共享。该方案依据国家和地方政策背景,如教育部《教育信息化“十三五”规划》和《教育信息化十年发展规划》,以信息技术的革命性影响为指导,推进教育信息化建设,实现教育思想和方法的创新。 技术发展为智慧校园建设提供了强有力的支撑。方案涵盖了互连互通、优质资源共享、宽带网络、移动APP、电子书包、电子教学白板、3D打印、VR虚拟教学等技术应用,以及大数据和云计算技术,提升了教学数据记录和分析水平。此外,教育资源公共服务平台、教育管理公共服务平台等平台建设,进一步提高了教学、管控的效率。 智慧校园系统由智慧教学、智慧管控和智慧办公三大部分组成,各自具有丰富的应用场景。智慧教学包括微课、公开课、精品课等教学资源的整合和共享,支持在线编辑、录播资源、教学分析等功能。智慧管控则通过平安校园、可视对讲、紧急求助、视频监控等手段,保障校园安全。智慧办公则利用远程视讯、无纸化会议、数字会议等技术,提高行政效率和会议质量。 教育录播系统作为智慧校园的重要组成部分,提供了一套满足学校和教育局需求的解决方案。它包括标准课室、微格课室、精品课室等,通过自动五机位方案、高保真音频采集、一键式录课等功能,实现了优质教学资源的录制和共享。此外,录播系统还包括互动教学、录播班班通、教育中控、校园广播等应用,促进了教育资源的均衡化发展。 智慧办公的另一重点是无纸化会议和数字会议系统的建设,它们通过高效的文件管理、会议文件保密处理、本地会议的音频传输和摄像跟踪等功能,实现了会议的高效化和集中管控。这些系统不仅提高了会议的效率和质量,还通过一键管控、无线管控等设计,简化了操作流程,使得会议更加便捷和环保。 总之,智慧校园信息化系统解决方案通过整合先进的信息技术和教学资源,不仅提升了教育质量和管理效率,还为实现教育均衡化和资源共享提供了有力支持,推动了教育现代化的进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值