果然我还是太菜了......

T1:

北京集训:20180318

北京集训:20180318
先分解成标准形式,然后每个质因数必须有最高次,然后状压DP?
发现并不可做......
然后写了10分的大力背包走了......
正解是容斥。

北京集训:20180318
然而他的公式挂了......
大概意思就是枚举我们有几个没有到最高次,然后用高维前缀和(积)进行DP。
关于高维前缀和可以看我以前的博客......
为什么考场没想起来......
考场10分代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 //#include<iostream>
 4 //#define debug cout
 5 //using namespace std;
 6 typedef long long int lli;
 7 const int maxn=5e2+1e1,maxk=22;
 8 const int mod=232792561;
 9 
10 lli f[2][maxn][maxk];
11 int n,k;
12 
13 inline int gcd(int x,int y) {
14     register int t;
15     while( t = x % y )
16         x = y , y = t;
17     return y;
18 }
19 inline int lcm(int x,int y) {
20     if( ! ( x && y ) ) return x | y;
21     return x / gcd(x,y) * y;
22 }
23 inline void trans(lli dst[maxn][maxk],const lli sou[maxn][maxk],int now) {
24     for(int i=0;i<=n;i++) {
25         const int tar = lcm(i,now);
26         if( tar > n ) continue;
27         for(int j=0;j<k;j++) ( dst[tar][(j+now)%k] += sou[i][j] ) %= mod;
28     }
29     for(int i=0;i<=n;i++)
30         for(int j=0;j<k;j++)
31             ( dst[i][j] += sou[i][j] ) %= mod;
32 }
33 
34 int main() {
35     static int T,cur;
36     scanf("%d",&T);
37     while(T--) {
38         memset(f,0,sizeof(f)) , cur = 0;
39         f[cur][0][0] = 1;
40         scanf("%d%d",&n,&k);
41         for(int i=1;i<=n;i++) {
42             cur ^= 1;
43             memset(f[cur],0,sizeof(f[1]));
44             trans(f[cur],f[cur^1],i);
45         }
46         printf("%lld\n",f[cur][n][0]);
47     }
48     return 0;
49 }
View Code

相关文章: