QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#266518 | #4318. 高性能计算导论集群登录密码复杂性策略 | jzh# | TL | 212ms | 35668kb | C++23 | 7.1kb | 2023-11-26 15:05:23 | 2023-11-26 15:05:24 |
Judging History
answer
#include<bits/stdc++.h>
#include <cassert>
using namespace std;
using ll = long long;
constexpr ll P = 1e9 + 7;
const int maxn = 2000;
ll qpow(ll a, ll b) {
ll ans = 1;
for(; b; a = a * a % P, b /= 2) {
if(b&1) ans = ans * a % P;
}
return ans;
}
namespace Polynomial {
using poly = vector<ll>;
poly operator += (poly &A, poly B) {
A.resize(max(A.size(), B.size()));
for(int i = 0 ; i < A.size() ; i ++) {
if(i<B.size()) A[i] = (A[i] + B[i]) % P;
}
return A;
}
poly operator + (poly A, poly B) {
return A += B;
}
poly operator -= (poly &A, poly B) {
A.resize(max(A.size(), B.size()));
for(int i = 0 ; i < A.size() ; i ++) {
if(i<B.size()) A[i] = (A[i] - B[i] + P) % P;
}
return A;
}
poly operator - (poly A, poly B) {
return A -= B;
}
poly operator * (poly A, ll b) {
for(auto &v: A) v = v * b % P;
return A;
}
poly operator * (poly A, poly B) {
poly C(A.size() + B.size() - 1);
for(int i = 0 ; i < A.size() ; i ++) {
for(int j = 0 ; j < B.size() ; j ++) {
C[i+j] = (C[i+j] + A[i] * B[j]) % P;
}
}
return C;
}
poly operator / (poly A, poly B) {
int n = A.size(), m = B.size();
poly ans = {0};
vector<poly>vec;
vec.push_back(B);
for(int i = 1 ; i + m <= n ; i ++) {
vec.push_back(vec.back() * poly{0, 1});
}
for(int i = n-1 ; i >= m-1 ; i --) {
ans = ans * poly{0, 1};
ans[0] = (A[i] * qpow(B[m-1], P-2)) % P;
A -= vec[i-m+1] * ans[0];
}
return ans;
}
poly operator % (poly A, poly B) {
A = A - (A/B)*B;
while(A.size()>1 and A.back()==0) A.pop_back();
return A;
}
poly POW(poly A, int k, poly p) {
poly ans = {1};
while(k) {
if(k%2==1) ans = (ans * A) % p;
A = A * A % p;
k /= 2;
}
return ans;
}
};
using namespace Polynomial;
ll dp[maxn][maxn];
vector<int>BM(const vector<int>&a) {
vector<int>v, last;
int k = -1, delta = 0;
for(int i = 0 ; i < (int)a.size() ; i ++) {
int tmp = 0;
for(int j = 0 ; j < (int)v.size(); j ++) {
tmp = (tmp + (ll)a[i-j-1] * v[j]) % P;
}
if(a[i]==tmp) continue;
if(k<0) {
k = i;
delta = (a[i] - tmp + P) % P;
v = vector<int>(i+1);
continue;
}
vector<int>u = v;
int val = (ll)(a[i] - tmp + P) * qpow(delta, P-2) % P;
if(v.size()<last.size() + i - k) v.resize(last.size() + i - k);
(v[i-k-1]+=val)%=P;
for(int j = 0 ; j < (int)last.size() ; j ++) {
v[i-k+j] = (v[i-k+j] - (ll)val * last[j]) % P;
if(v[i-k+j]<0) v[i-k+j] += P;
}
if((int)u.size() - i < (int)last.size()-k) {
last = u;
k = i;
delta = a[i] - tmp;
if(delta<0) delta += P;
}
}
for(auto &x: v) x = (P-x) % P;
v.insert(begin(v), 1);
return v;
}
struct Aho_Corasick {
int nxt[maxn][130], fail[maxn];
bool vis[maxn];
int root, idx;
void clear() {
memset(nxt[0], 0, sizeof(nxt[0]));
memset(vis, 0, sizeof(vis));
root = idx = 0;
}
int newnode() {
fail[++idx] = 0; memset(nxt[idx], 0, sizeof(nxt[idx]));
return idx;
}
int insert(int pre, int ch) {
return nxt[pre][ch]?nxt[pre][ch]:nxt[pre][ch] = newnode();
}
void insert(const char *s) {
//cout << s << endl;
int now = root;
for(int i = 0 ; s[i] ; i ++) {
now = insert(now, s[i]);
}
vis[now] = true;
}
void build() {
fail[root] = root;
queue<int>q;
for(int i = 0 ; i < 130 ; i ++) if(nxt[0][i]) q.push(nxt[0][i]);
while(!q.empty()) {
int h = q.front(); q.pop();
for(int i = 0 ; i < 130 ; i ++) {
if(!nxt[h][i]) {
nxt[h][i] = nxt[fail[h]][i];
}
else{
int tmp = nxt[h][i];
fail[tmp] = nxt[fail[h]][i];
q.push(tmp);
}
}
}
}
ll calc(int l, int r, const vector<int>sigma) {
memset(dp, 0, sizeof(dp));
dp[0][root] = 1;
int n = idx + 10;
for(int i = 0 ; i < n ; i ++) {
for(int st = 0 ; st <= idx ; st ++) {
if(!dp[i][st] or vis[st]) continue;
for(auto &ch: sigma) {
if(vis[nxt[st][ch]]) continue;
(dp[i+1][nxt[st][ch]] += dp[i][st]) %= P;
}
}
}
vector<int>vec(n);
for(int i = 0 ; i < n ; i ++) {
for(int st = 0 ; st <= idx ; st ++) {
vec[i] = (vec[i] + dp[i][st]) % P;
}
}
auto p = BM(vec);
auto temp = poly(begin(p), end(p)) * poly{-1, 1};
auto res1 = POW({0, 1}, r+1, temp);
auto res2 = POW({0, 1}, l, temp);
//for(auto &v: res1) cout << v << ' '; cout << endl;
//for(auto &v: res2) cout << v << ' '; cout << endl;
auto res = (res1-res2) / poly{-1, 1};
ll ans = 0;
for(int i = 0 ; i < res.size() ; i ++) {
ans = (ans + res[i] * vec[i]) % P;
}
return ans;
}
}acam;
void solve() {
/*vector<int>a = {3, 4, 6, 10, 18, 34};
auto vec = BM(a);
for(auto &v: vec) cout << v << ' '; cout << endl;*/
ll l, r, a, b; cin >> l >> r >> a >> b;
auto add_num = [&]() {
for(char ch = '0' ; ch <= '9' ; ch ++) {
string temp(a, ch);
acam.insert(temp.c_str());
}
for(char ch = '0' ; ch + b - 1 <= '9' ; ch ++) {
string temp;
for(char t = ch ; t <= ch + b - 1 ; t ++) temp += t;
acam.insert(temp.c_str());
}
for(char ch = '9' ; ch - b + 1 >= '0' ; ch --) {
string temp;
for(char t = ch ; t >= ch - b + 1 ; t --) temp += t;
acam.insert(temp.c_str());
}
};
auto add_ch = [&]() {
for(char ch = 'a' ; ch <= 'z' ; ch ++) {
string temp(a, ch);
acam.insert(temp.c_str());
}
for(char ch = 'A' ; ch <= 'Z' ; ch ++) {
string temp(a, ch);
acam.insert(temp.c_str());
}
for(char ch = 'a' ; ch + b - 1 <= 'z' ; ch ++) {
string temp;
for(char t = ch ; t <= ch + b - 1 ; t ++) temp += t;
acam.insert(temp.c_str());
}
for(char ch = 'z' ; ch - b + 1 >= 'a' ; ch --) {
string temp;
for(char t = ch ; t >= ch - b + 1 ; t --) temp += t;
acam.insert(temp.c_str());
}
for(char ch = 'A' ; ch + b - a <= 'Z' ; ch ++) {
string temp;
for(char t = ch ; t <= ch + b - 1 ; t ++) temp += t;
acam.insert(temp.c_str());
}
for(char ch = 'Z' ; ch - b + 1 >= 'A' ; ch --) {
string temp;
for(char t = ch ; t >= ch - b + 1 ; t --) temp += t;
acam.insert(temp.c_str());
}
};
ll ans = 0;
// all
acam.clear();
add_num();
add_ch();
acam.build();
vector<int>sigma;
for(char ch = '0' ; ch <= '9' ; ch ++) sigma.push_back(ch);
for(char ch = 'a' ; ch <= 'z' ; ch ++) sigma.push_back(ch);
for(char ch = 'A' ; ch <= 'Z' ; ch ++) sigma.push_back(ch);
ans = (ans + acam.calc(l, r, sigma)) % P;
// only number
acam.clear();
add_num();
acam.build();
sigma = {};
for(char ch = '0' ; ch <= '9' ; ch ++) sigma.push_back(ch);
ans = (ans - acam.calc(l, r, sigma)) % P;
// only char
acam.clear();
add_ch();
acam.build();
sigma = {};
for(char ch = 'a' ; ch <= 'z' ; ch ++) sigma.push_back(ch);
for(char ch = 'A' ; ch <= 'Z' ; ch ++) sigma.push_back(ch);
ans = (ans - acam.calc(l, r, sigma)) % P;
cout << (ans + P) % P << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 212ms
memory: 35668kb
input:
1 1 6 14
output:
0
result:
ok single line: '0'
Test #2:
score: -100
Time Limit Exceeded
input:
107140316 406944816 6 13