zoukankan      html  css  js  c++  java
  • Painful Bases LightOJ

    Painful Bases LightOJ - 1021

    题意:给出0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F中的一些字符(不重复)还有一个进制base,求这些字符的排列形成的base进制数中,有多少个能被k整除。

    方法:

    正常的做法:

    http://blog.csdn.net/chenzhenyu123456/article/details/51155038

    自己的做法(常数很大,仅做记录):

    ans[i][S][j]表示i进制下,S集合中数字可用,总产生余数为j时方案数

    digit(S)表示S集合中元素数量。那么,当前数字为一个digit(S)位的base进制数,其第digit(S)位的值转换为10进制后除以k产生的余数就是j。

    ans[i][S][j]=sum{ans[i][S-p][(j+k-pow(i,digit(S)-1)*p%k)%k}

    其含义:把S中任意一个数字p当做首位,首位产生的余数$pow(i,digit(S)-1)*p%k$,然后剩下数字的余数应该是$(j+k-pow(i,digit(S)-1)*p%k)%k$。

    实际使用时,这样定义状态会爆空间,因此只能把i的一维舍去,每组数据都重新算。

    错误次数:2

    原因:

    1.用循环,被卡常,改成了记忆化搜索。

    2.在用循环的时候,为了卡常,改了循环内外层,但不正确。

    卡常记录:把记录a^b改成记录所有a^b%k,时间缩短到1/3。

     1 #include<cstdio>
     2 #include<cstring>
     3 typedef long long LL;
     4 LL ans[70000][22];
     5 LL T,TT;
     6 bool ok[20];
     7 char ss[20];
     8 LL popcount[70000];
     9 LL powww[30][30][30];
    10 LL base,k;
    11 LL poww(LL a,LL b)
    12 {
    13     if(powww[a][b][k])    return powww[a][b][k];
    14     LL base=a,ans=1,b1=b;
    15     while(b)
    16     {
    17         if(b&1)    ans=ans*base%k;
    18         b>>=1;
    19         base=base*base%k;
    20     }
    21     return powww[a][b1][k]=ans;
    22 }
    23 LL get(LL s,LL j)
    24 {
    25     if(ans[s][j]!=-1)    return ans[s][j];
    26     int j1;
    27     ans[s][j]=0;
    28     for(j1=0;j1<base;j1++)
    29         if(s&(1<<j1))
    30             ans[s][j]+=get(s^(1<<j1),(j+k-poww(base,__builtin_popcount(s)-1)*j1%k)%k);
    31     return ans[s][j];
    32 }
    33 int main()
    34 {
    35     LL i,tt;
    36     for(i=1;i<(1<<16);i++)
    37         popcount[i]=__builtin_popcountll(i);
    38     scanf("%lld",&T);
    39     for(TT=1;TT<=T;TT++)
    40     {
    41         tt=0;
    42         memset(ok,0,sizeof(ok));
    43         memset(ans,-1,sizeof(ans));
    44         scanf("%lld%lld",&base,&k);
    45         ans[0][0]=1;
    46         scanf("%s",ss);
    47         for(i=0;i<strlen(ss);i++)
    48             if(ss[i]>='0'&&ss[i]<='9')
    49                 ok[ss[i]-'0']=1;
    50             else
    51                 ok[ss[i]-'A'+10]=1;
    52         for(i=0;i<base;i++)
    53             if(ok[i])
    54                 tt^=(1<<i);
    55         printf("Case %lld: %lld
    ",TT,get(tt,0));
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    HTML5 浏览器返回按钮/手机返回按钮事件监听
    Asp.Net Core获取请求信息/获取请求地址
    Asp.Net 获取物理路径
    .Net AppDomain详解(二)
    .Net AppDomain详解(一)
    asp.net core部署到iis中出现 HTTP Error 502.5
    Asp.Net Core 静态文件目录操作
    Asp.Net Core Web相对路径、绝对路径整理
    .Net Core Bitmap位图处理
    ngRx 官方示例分析
  • 原文地址:https://www.cnblogs.com/hehe54321/p/loj-1021.html
Copyright © 2011-2022 走看看