QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#266553#4318. 高性能计算导论集群登录密码复杂性策略jzhAC ✓365ms36384kbC++236.9kb2023-11-26 15:21:112023-11-26 15:21:12

Judging History

This is the latest submission verdict.

  • [2023-11-26 15:21:12]
  • Judged
  • Verdict: AC
  • Time: 365ms
  • Memory: 36384kb
  • [2023-11-26 15:21:11]
  • Submitted

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();
		while(B.back()==0) B.pop_back();
		poly ans = {0};
		if(n<m) return ans;
		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.back() * qpow(B[m-1], P-2)) % P;
			A -= vec[i-m+1] * ans[0];
			A.pop_back();
		}
		return ans;
	}
	poly operator % (poly A, poly B) {
		A = A - (A/B)*B;
		A.resize(B.size());
		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);
		reverse(begin(p), end(p));

		auto temp = poly(begin(p), end(p)) * poly{P-1, 1};

		auto res1 = POW({0, 1}, r+1, temp);
		auto res2 = POW({0, 1}, l, temp);

		auto res = (res1-res2) / poly{P-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() {
	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;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 222ms
memory: 36384kb

input:

1 1 6 14

output:

0

result:

ok single line: '0'

Test #2:

score: 0
Accepted
time: 331ms
memory: 36124kb

input:

107140316 406944816 6 13

output:

192490578

result:

ok single line: '192490578'

Test #3:

score: 0
Accepted
time: 349ms
memory: 36028kb

input:

779830894 854589440 6 16

output:

142613425

result:

ok single line: '142613425'

Test #4:

score: 0
Accepted
time: 91ms
memory: 35212kb

input:

820947500 832029867 6 25

output:

334755990

result:

ok single line: '334755990'

Test #5:

score: 0
Accepted
time: 74ms
memory: 35800kb

input:

531362238 979634526 6 26

output:

628390760

result:

ok single line: '628390760'

Test #6:

score: 0
Accepted
time: 56ms
memory: 35476kb

input:

580120176 615170139 2 24

output:

282232431

result:

ok single line: '282232431'

Test #7:

score: 0
Accepted
time: 192ms
memory: 35540kb

input:

609381043 653379818 2 13

output:

803190890

result:

ok single line: '803190890'

Test #8:

score: 0
Accepted
time: 252ms
memory: 35972kb

input:

137169046 882295293 4 17

output:

487036819

result:

ok single line: '487036819'

Test #9:

score: 0
Accepted
time: 202ms
memory: 35784kb

input:

394493680 588692626 4 20

output:

99083012

result:

ok single line: '99083012'

Test #10:

score: 0
Accepted
time: 166ms
memory: 36172kb

input:

722139370 843455409 3 20

output:

187518918

result:

ok single line: '187518918'

Test #11:

score: 0
Accepted
time: 137ms
memory: 35680kb

input:

154981461 843412687 4 6

output:

799306362

result:

ok single line: '799306362'

Test #12:

score: 0
Accepted
time: 365ms
memory: 36036kb

input:

999999999 1000000000 6 15

output:

227192434

result:

ok single line: '227192434'

Test #13:

score: 0
Accepted
time: 88ms
memory: 35348kb

input:

892758405 994840518 4 4

output:

945734811

result:

ok single line: '945734811'

Test #14:

score: 0
Accepted
time: 362ms
memory: 36108kb

input:

536870911 973078527 6 14

output:

598094194

result:

ok single line: '598094194'

Test #15:

score: 0
Accepted
time: 310ms
memory: 36332kb

input:

536870912 973078527 6 15

output:

803373842

result:

ok single line: '803373842'

Test #16:

score: 0
Accepted
time: 358ms
memory: 36312kb

input:

333333333 333333333 6 14

output:

867976976

result:

ok single line: '867976976'

Test #17:

score: 0
Accepted
time: 7ms
memory: 35044kb

input:

66025887 800841810 2 2

output:

141443913

result:

ok single line: '141443913'

Test #18:

score: 0
Accepted
time: 134ms
memory: 35508kb

input:

37821660 191789705 5 5

output:

232561519

result:

ok single line: '232561519'

Test #19:

score: 0
Accepted
time: 305ms
memory: 36052kb

input:

668000825 930344057 6 9

output:

597839207

result:

ok single line: '597839207'

Test #20:

score: 0
Accepted
time: 320ms
memory: 35940kb

input:

692413584 717112316 6 10

output:

912537114

result:

ok single line: '912537114'