【問題描述】
dzy 定義乙個n^2 位的數的生成矩陣a 為乙個大小為n*n 且aij 為這個數的第i*n+j-n位的矩陣。
現在dzy 有乙個數n^2 位的數k,他想知道所有小於等於k 的數的n*n 生成矩陣有多少種。(如果不足n^2 位則補字首零)
【輸入】
第一行乙個數n,第二行乙個n^2 位的數k
【輸出】
僅一行表示答案,答案可能很大,你只需輸出答案對10^9 + 7 取模後的結果。
【輸入輸出樣例】
water.in
2 1000
water.out
954【資料規模和約定】
對於30% 的資料n<=2
對於100% 的資料n <=1000,且n為偶數
【提示】
如果兩個生成矩陣在其中乙個旋轉180 度後可以重疊,則稱這兩個矩陣是相同的。
【題解】
數字dp
演算法1:
直接暴力到底,複雜度是
,期望得分30分。
演算法2:
令 f(i,n) 表示把i在 n2位十進位制下反轉得到的數,則有:
分子中的兩項都可以用數字dp求出,首先考慮第一項:
令表示dp的狀態,表示 k 前 i 位組成的數,表示 k 後 i 位組成的數,表示k 前 i 位倒序組成的數,則定義:
顯然這是可以遞推的。
接下來考慮第二項:
求出這兩項後代入上式即可得到答案,時間複雜度 o(n2 ),期望得分100 分。
#include
#include
#include
#include
#include
#include
#define fp(i,a,b) for(int i=a;i<=b;i++)
#define fq(i,a,b) for(int i=a;i>=b;i--)
#define il inline
#define ll long long
using
namespace
std;
const
int mod=1e9+7;
const
int m=500000004;
const
int maxn=1010*1010;
ll n,m,ans,cnt,a[maxn],f[maxn][2][2];
char s[maxn];
il int gi()
il void init()
il void work()}}
cnt=(f[n][0][1]+f[n][1][1])%mod;
cnt=(cnt-f[n/2][1][1]-f[n/2][1][0]-f[n/2][0][1])%mod;
cnt=cnt*m%mod;
ans=((ans-cnt)%mod+mod)%mod;
printf("%lld\n",ans);
}int main()
大水題(容斥原理)
給出乙個數n,求1到n中,有多少個數不是2 5 11 13的倍數。本題有多組輸入 每行乙個數n,1 n 10 18.每行輸出輸出不是2 5 11 13的倍數的數共有多少。示例1 15 4 1 3 7 9 容斥原理 四個集合 a1 a2 a3 a4 a1 a2 a3 a4 a1 a2 a1 a3 a1...
BZOJ 斜率優化大水題(集)2 1096
includeusing namespace std const int maxn 1000010 long long a maxn p maxn x maxn c maxn s maxn int n long long q maxn dp maxn y maxn int main int head...
HDU 2547 無劍無我 大水題
problem description 北宋末年,奸臣當道,宦官掌權,外侮日亟,遼軍再犯。時下戰火連連,烽煙四起,哀鴻遍野,民不聊生,又有眾多能人異士群起而反,天下志士雲集響應,景糧影從。值此危急存亡之秋,在乙個與世隔絕的地方 mca山上一位江湖人稱 英雄 出來 的人正在為抗擊遼賊研究劍法,終於於一...