https://codeforces.com/gym/102091
题意:找出n行杨辉三角中元素%7==0的个数。
分析:首先考虑n很大,所以直接打表,用*标记出7的倍数的位置。
#include "bits/stdc++.h"
using namespace std;
long long f[1004][1004];
int main() {
memset(f,0, sizeof(f));
f[1][1]=1;
for (int i = 2; i <= 1000; ++i) {
for (int j = 1; j <= i; ++j) {
f[i][j]=(f[i-1][j]+f[i-1][j-1])%7;
}
}
for (int i = 2; i <= 1000; ++i) {
for (int j = 1; j <= i; ++j) {
if (f[i][j] % 7 == 0)
printf("*");
else printf(".");
}
puts("");
}
}
由于数据量很大,所以把字体的size调到4
OK,现在很容易找出规律了,可以看出1到7^1-1是一个整块,7^1到7^2-1是一个整块,对于一个右边界是7^i-1整块来讲,设F[i]是右边界是7^i-1整块中的数量。那么
我们现在就可以找到整块的答案了,然后多出来的一部分直接递归找就可以了,注意一下取模就可以过了。(由于这个题的输入量并不是很多,所以快读可以有但没必要
#include "bits/stdc++.h"
namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if (pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(long long &x) {
char ch;
while (blank(ch = nc()));
if (IOerror) return;
for (x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
using namespace fastIO;
using namespace std;
const int mod = 1e9 + 7;
map<long long, long long> mp;
long long qk(long long a, long long n) {
long long ans = 1;
while (n) {
if (n & 1)ans = ans * a % mod;
n >>= 1;
a = a * a % mod;
}
return ans;
}
long long inv2 = qk(2, mod - 2);
void init() {
long long base = 7;
mp[base - 1] = 0;
base = 49;
while (base <= 1000000000000000000) {
long long temp = base / 7;
mp[base - 1] = (28LL * mp[base / 7LL - 1LL] % mod + 21LL * ((temp - 1 + mod) % mod) % mod * (temp % mod) % mod * inv2 % mod) % mod;
base *= 7;
}
}
long long getsum(long long n) {
if (n <= 6)return 0;
long long ans = 0;
long long base = 0;
for (auto it = mp.begin(); it != mp.end(); ++it) {
long long a = it->first, b = it->second;
if (a <= n) {
ans = b;
base = a;
}
}
base++;
long long a = base;
long long time = 1;
long long now = base % mod * ((base - 1 + mod) % mod) % mod * inv2 % mod;
while (a + base <= n) {
ans += now * time % mod;
ans %= mod;
time++;
ans += mp[base - 1] * time % mod;
ans %= mod;
a += base;
}
if (n - a + 1 == base)
ans += (base % mod) * ((base - 1 + mod) % mod) % mod * inv2 % mod * time % mod;
else
ans += (n - a + 1) % mod * ((((base - 1 + mod) % mod) + ((base + mod - 1) % mod)) % mod - n % mod + a % mod + mod) % mod * inv2 % mod * time % mod;
ans %= mod;
ans = (ans + (time + 1) * getsum(n - a) % mod) % mod;
return ans;
}
int main() {
int t;
init();
cin >> t;
long long n = 0;
int KASE = 1;
while (t--) {
n++;
read(n);
//cin>>n;
printf("Case %d: %lld\n", KASE++, getsum(n));
}
}