博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(dp)CodeForces - 300D Painting Square
阅读量:5020 次
发布时间:2019-06-12

本文共 3377 字,大约阅读时间需要 11 分钟。

Vasily the bear has got a large square white table of n rows and n columns. The table has got a black border around this table.

 
The example of the initial table at n = 5.

Vasily the bear wants to paint his square table in exactly k moves. Each move is sequence of actions:

  1. The bear chooses some square inside his table. At that the square must have a black border painted around it. Also, the square shouldn't contain a black cell. The number of cells in the square shouldn't be less than 2.
  2. The bear chooses some row and some column inside the chosen square. Then he paints each cell of this row and this column inside the chosen square. After that the rectangles, formed by the square's border and the newly painted cells, must be squares of a non-zero area.
An example of correct painting at n = 7 и k = 2.

The bear already knows numbers n and k. Help him — find the number of ways to paint the square in exactly k moves. Two ways to paint are called distinct if the resulting tables will differ in at least one cell. As the answer can be rather large, print the remainder after dividing it by 7340033.

Input

The first line contains integer q (1 ≤ q ≤ 105) — the number of test data.

Each of the following q lines contains two integers n and k (1 ≤ n ≤ 109, 0 ≤ k ≤ 1000) — the size of the initial table and the number of moves for the corresponding test.

Output

For each test from the input print the answer to the problem modulo 7340033. Print the answers to the tests in the order in which the tests are given in the input.

Example

Input
8 1 0 1 1 3 0 3 1 2 0 2 1 3 2 7 2
Output
1 0 1 1 1 0 0 4

Note

All possible painting ways for the test n = 7 and k = 2 are:

 

这个题不仔细读题容易读错,首先必须分成正方形而非矩形,其次some row some column 指的是某一条行、列。

明确是分成正方形后显然可知,只有边长为奇数的的正方形才可以继续分下去。显然对于某边长x的正方形,每次只分其左上角的(初始时分整体),最多分 x二进制下末尾1的个数次。很自然的就可以想到一种递推。

用dp[i][j]表示边长为“i”(二进制下尾数1的个数)的正方形分j次的情况数。

dp[i][x]=∑(x1+x2+x3+x4=x xi>=0)dp[i-1][x1]*dp[i-1][x2]*dp[i-1][x3]*dp[i-1][x4]

这样一个∑还是比较麻烦,可以通过预处理(类似倍增的想法)先用an[x]表示对两个边长为i-1的正方向一共操作x次的情况数,显然an[x]=Σ(x1+x2=x,xi>=0)dp[i-1]*[x1]*dp[i-1][x2]

则dp[i][x]=Σ(x1+x2=x,xi>=0)an[x1]*an[x2] ,降低了原本n^3的复杂度为n^2(虽然n最大也不过30,影响可以忽略不计)

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #define mp make_pair14 //#define P make_pair15 #define MIN(a,b) (a>b?b:a)16 //#define MAX(a,b) (a>b?a:b)17 typedef long long ll;18 typedef unsigned long long ull;19 const int MAX=1e3+5;20 const int MAX_V=2e4+5;21 const ll INF=2e11+5;22 const double M=4e18;23 using namespace std;24 //const int MOD=1e9+7;25 const ll MOD=7340033;26 typedef pair
pii;27 const double eps=0.000000001;28 #define rank rankk29 int q,n,k,mi;30 ll dp[31][MAX],num[MAX];31 int main()32 {33 scanf("%d",&q);34 dp[0][0]=1LL;35 for(int i=1;i<=30;i++)36 {37 dp[i][0]=1LL;38 memset(num,0,sizeof(num));39 for(int s=0;s<=1000;s++)40 for(int j=0;j<=1000-s;j++)41 num[s+j]=(num[s+j]+dp[i-1][s]*dp[i-1][j]%MOD)%MOD;42 for(int s=0;s<1000;s++)43 for(int j=0;j<1000-s;j++)44 dp[i][s+j+1]=(dp[i][s+j+1]+num[s]*num[j]%MOD)%MOD;45 }46 while(q--)47 {48 scanf("%d%d",&n,&k);49 mi=0;50 while(n>1&&(n&1))51 n>>=1,++mi;52 printf("%I64d\n",dp[mi][k]);53 }54 return 0;55 }

 

转载于:https://www.cnblogs.com/quintessence/p/6993571.html

你可能感兴趣的文章
机器学习好网站
查看>>
python 中的 sys , os 模块用法总结
查看>>
解题:国家集训队 Middle
查看>>
响应者链
查看>>
指针从函数内部带回返回值
查看>>
在使用webView播放flash或视频文件时无法关闭声音的问题
查看>>
redhat 7 源码安装 mysql5.5.49
查看>>
CCP浅谈
查看>>
NAT虚拟网络配置
查看>>
c#部分---需要实例化的内容;
查看>>
销售类
查看>>
技术项目,问题
查看>>
线程池总结
查看>>
Learning to rank (software, datasets)
查看>>
git常见问题
查看>>
.NETFramework:template
查看>>
HM16.0之帧内模式——xCheckRDCostIntra()函数
查看>>
Jmeter性能测试 入门
查看>>
安卓动画有哪几种?他们的区别?
查看>>
Nodejs学习总结 -Express入门(一)
查看>>