結果
| 問題 |
No.515 典型LCP
|
| コンテスト | |
| ユーザー |
Coki628
|
| 提出日時 | 2021-01-26 17:32:37 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 762 ms / 1,000 ms |
| コード長 | 6,261 bytes |
| コンパイル時間 | 9,499 ms |
| コンパイル使用メモリ | 280,068 KB |
| 最終ジャッジ日時 | 2025-01-18 08:23:06 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 |
ソースコード
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using pii = pair<int, int>;
using vvl = vector<vector<ll>>;
using vvi = vector<vector<int>>;
using vvpll = vector<vector<pll>>;
#define rep(i, a, b) for (ll i=(a); i<(b); i++)
#define rrep(i, a, b) for (ll i=(a); i>(b); i--)
#define pb push_back
#define tostr to_string
#define ALL(A) A.begin(), A.end()
#define elif else if
// constexpr ll INF = LONG_LONG_MAX;
constexpr ll INF = 1e18;
constexpr ll MOD = 1000000007;
const string digits = "0123456789";
const string ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
const string ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string ascii_letters = ascii_lowercase + ascii_uppercase;
template<typename T> vector<vector<T>> list2d(int N, int M, T init) { return vector<vector<T>>(N, vector<T>(M, init)); }
template<typename T> vector<vector<vector<T>>> list3d(int N, int M, int L, T init) { return vector<vector<vector<T>>>(N, vector<vector<T>>(M, vector<T>(L, init))); }
template<typename T> vector<vector<vector<vector<T>>>> list4d(int N, int M, int L, int O, T init) { return vector<vector<vector<vector<T>>>>(N, vector<vector<vector<T>>>(M, vector<vector<T>>(L, vector<T>(O, init)))); }
vector<ll> LIST(ll N) { vector<ll> A(N); rep(i, 0, N) cin >> A[i]; return A; }
void print(ld out) { cout << fixed << setprecision(15) << out << '\n'; }
void print(double out) { cout << fixed << setprecision(15) << out << '\n'; }
template<typename T> void print(T out) { cout << out << '\n'; }
template<typename T1, typename T2> void print(pair<T1, T2> out) { cout << out.first << ' ' << out.second << '\n'; }
template<typename T> void print(vector<T> A) { rep(i, 0, A.size()) { cout << A[i]; cout << (i == A.size()-1 ? '\n' : ' '); } }
template<typename T> void print(set<T> S) { vector<T> A(S.begin(), S.end()); print(A); }
void Yes() { print("Yes"); }
void No() { print("No"); }
void YES() { print("YES"); }
void NO() { print("NO"); }
ll floor(ll a, ll b) { if (a < 0) { return (a-b+1) / b; } else { return a / b; } }
ll ceil(ll a, ll b) { if (a >= 0) { return (a+b-1) / b; } else { return a / b; } }
pll divmod(ll a, ll b) { ll d = a / b; ll m = a % b; return {d, m}; }
template<typename T> bool chmax(T &x, T y) { return (y > x) ? x = y, true : false; }
template<typename T> bool chmin(T &x, T y) { return (y < x) ? x = y, true : false; }
template<typename T> T sum(vector<T> A) { T res = 0; for (T a: A) res += a; return res; }
template<typename T> T max(vector<T> A) { return *max_element(ALL(A)); }
template<typename T> T min(vector<T> A) { return *min_element(ALL(A)); }
ll toint(string s) { ll res = 0; for (char c : s) { res *= 10; res += (c - '0'); } return res; }
int toint(char num) { return num - '0'; }
char tochar(int num) { return '0' + num; }
int ord(char c) { return (int)c; }
char chr(int a) { return (char)a; }
ll pow(ll x, ll n) { ll res = 1; rep(_, 0, n) res *= x; return res; }
ll pow(ll x, ll n, int mod) { ll res = 1; while (n > 0) { if (n & 1) { res = (res * x) % mod; } x = (x * x) % mod; n >>= 1; } return res; }
int popcount(ll S) { return __builtin_popcountll(S); }
ll gcd(ll a, ll b) { return __gcd(a, b); }
ll lcm(ll x, ll y) { return (x * y) / gcd(x, y); }
template<typename T> int bisect_left(vector<T> &A, T val) { return lower_bound(ALL(A), val) - A.begin(); }
template<typename T> int bisect_right(vector<T> &A, T val) { return upper_bound(ALL(A), val) - A.begin(); }
template<typename Monoid>
struct SegTree {
using F = function<Monoid(Monoid, Monoid)>;
int sz;
vector<Monoid> seg;
const F f;
const Monoid M1;
SegTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
sz = 1;
while(sz < n) sz <<= 1;
seg.assign(2 * sz, M1);
}
SegTree(const F f, const Monoid &M1) : f(f), M1(M1) {}
void resize(int n) {
sz = 1;
while(sz < n) sz <<= 1;
seg.resize(2 * sz, M1);
}
void clear() {
seg.clear();
}
void set(int k, const Monoid &x) {
seg[k+sz] = x;
}
void build() {
for(int k = sz - 1; k > 0; k--) {
seg[k] = f(seg[2*k], seg[2*k+1]);
}
}
void build(vector<Monoid> &A) {
int n = A.size();
resize(n);
rep(i, 0, n) set(i, A[i]);
build();
}
void update(int k, const Monoid &x) {
k += sz;
seg[k] = x;
while(k >>= 1) {
seg[k] = f(seg[2*k], seg[2*k+1]);
}
}
Monoid query(int a, int b) {
Monoid L = M1, R = M1;
for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
if(a & 1) L = f(L, seg[a++]);
if(b & 1) R = f(seg[--b], R);
}
return f(L, R);
}
Monoid operator[](const int &k) const {
return seg[k+sz];
}
Monoid all() {
return seg[1];
}
};
pair<vector<ll>, vector<ll>> gen(ll M, ll n, ll x, ll d) {
vector<ll> A(M), B(M);
rep(i, 0, M) {
A[i] = (x/(n-1))+1;
B[i] = (x%(n-1))+1;
if (A[i] > B[i]) {
swap(A[i], B[i]);
} else {
B[i]++;
}
x = (x+d)%(n*(n-1));
}
return {A, B};
}
ll get_lcp(const string &s, const string &t) {
ll i = 0;
while (i < s.size() and i < t.size() and s[i] == t[i]) i++;
return i;
}
int main() {
cin.tie(0);
ios::sync_with_stdio(false);
ll N;
cin >> N;
vector<pair<string, ll>> S(N);
rep(i, 0, N) {
cin >> S[i].first;
S[i].second = i;
}
sort(ALL(S));
vector<ll> toi(N);
rep(i, 0, N) {
toi[S[i].second] = i;
}
vector<ll> lcp(N-1);
rep(i, 0, N-1) {
lcp[i] = get_lcp(S[i].first, S[i+1].first);
}
SegTree<ll> seg([](ll a, ll b) { return min(a, b); }, INF);
seg.build(lcp);
ll M, x, d;
cin >> M >> x >> d;
auto [A, B] = gen(M, N, x, d);
ll ans = 0;
rep(i, 0, M) {
A[i]--;
B[i]--;
ll l = toi[A[i]];
ll r = toi[B[i]];
if (l > r) swap(l, r);
ans += seg.query(l, r);
}
print(ans);
return 0;
}
Coki628