QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#181542 | #7219. The Mighty Spell | ucup-team288 | RE | 21ms | 14812kb | C++20 | 4.3kb | 2023-09-16 20:28:20 | 2023-09-16 20:28:21 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i64 = long long;
#define pb emplace_back
#define AI(i) begin(i), end(i)
template<class T> bool chmin(T &a, T b) { return b < a && (a = b, true); }
template<class T> bool chmax(T &a, T b) { return a < b && (a = b, true); }
#ifdef KEV
#define DE(args...) kout("[ " + string(#args) + " ] = ", args)
void kout() { cerr << endl; }
template<class T, class ...U> void kout(T a, U ...b) { cerr << a << ' ', kout(b...); }
template<class T> void debug(T l, T r) { while (l != r) cerr << *l << " \n"[next(l)==r], ++l; }
#else
#define DE(...) 0
#define debug(...) 0
#endif
const int MAX_N = 200010, MAX_M = 51, p = 1e9 + 7;
using ap = array<int, MAX_M>;
int n, m;
int c[MAX_N];
ll cnt[MAX_M];
ll w[MAX_N], iw[MAX_N], p2[MAX_N];
ll wb[MAX_N], iwb[MAX_N];
ll pf[MAX_N];
ap lst[MAX_N];
ll inv[MAX_N];
ll g(ll x) {
vector<int> c = {2, 3, 3, 3};
ll s = 0;
for (ll z: c)
s = (s * x + z) % p;
return s;
return (2 * x * x % p * x % p
+ 3 * x * x % p
+ 3 * x + 3) % p;
}
void mul(ll &a, ll b) {
a = (a * b) % p;
}
void add(ll &a, ll b) {
a = (a + b) % p;
}
ll bin_pow(ll v, ll t) {
ll ret = 1;
for (;t;t>>=1, mul(v, v))
if (t&1) mul(ret, v);
return ret;
}
void init() {
inv[0] = inv[1] = 1;
p2[0] = 1;
p2[1] = 2;
for (int i = 2;i < MAX_N;++i) {
inv[i] = (p-p/i) * inv[p % i] % p;
p2[i] = p2[i-1] * 2 % p;
}
for (int i = 1;i < MAX_N;++i)
pf[i] = (pf[i-1] + g(i) * bin_pow(inv[2], i)) % p;
}
//ll get_g(ll l, ll r, ll clen) {
// ll ret = 0;
// for (int i = l;i <= r;++i) {
// add(ret, p2[clen - i] * f(i) % p);
// }
// return ret;
//}
ll cont(ll l, ll r) {
vector<int> has(m+1);
for (int i = l;i <= r;++i)
has[ c[i] ] = true;
vector<int> cnt(m+1);
for (int i = 1;i+1 < l;++i)
++cnt[ c[i] ];
for (int i = r+2;i <= n;++i)
++cnt[ c[i] ];
ll ret = g(r - l + 1);
for (int i = 1;i <= m;++i) {
if (has[i]) mul(ret, p2[cnt[i]]);
else mul(ret, p2[cnt[i]] - 1);
}
return ret;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
init();
DE(g(1), g(2), g(3), g(2) + g(3) + 2 * g(1));
cin >> n >> m;
for (int i = 1;i <= n;++i)
cin >> c[i];
for (int i = 1;i <= n;++i) {
lst[i] = lst[i-1];
lst[i][c[i]] = i;
++cnt[c[i]];
}
for (int i = 1;i <= m;++i) {
w[i] = p2[cnt[i]] - 1;
iw[i] = bin_pow(w[i], p-2);
if (cnt[i] > 0)
wb[i] = p2[cnt[i]-1] - 1;
else
wb[i] = 0;
iwb[i] = bin_pow(wb[i], p-2);
//DE(i, w[i]);
}
ll res = 0;
for (int r = 1;r <= n;++r) {
if (r+1 <= n && cnt[ c[r+1] ] == 1) continue;
int nxt_c = c[r+1];
if (nxt_c) {
--cnt[nxt_c];
swap(w[nxt_c], wb[nxt_c]);
swap(iw[nxt_c], iwb[nxt_c]);
assert(w[nxt_c] != 0);
}
ll cur_v = 1;
for (int i = 1;i <= m;++i) {
DE(i, cnt[i]);
//mul(cur_v, p2[ cnt[i] ]-1);
mul(cur_v, w[i]);
}
vector<int> sid(m+1); iota(AI(sid), 0);
sort(AI(sid), [&](int a, int b) {
return lst[r][a] > lst[r][b];
});
DE(r);
int clen = 0;
{
// p1 == 0
int clen = 0;
ll sc = 1;
for (int i = 1;i <= m;++i)
if (lst[r][i] != 0)
clen += cnt[i];
else
mul(sc, w[i]);
ll v = g(r) * p2[clen-r] % p * sc % p;
//assert(v == cont(1, r));
add(res, v);
}
for (int i = 1;i <= m;++i) assert(w[i] * iw[i] % p == 1);
for (int j = 0;;++j) {
int p1 = lst[r][ sid[j] ];
clen += cnt[ sid[j] ];
if (p1 == 0) {
break;
// len = r
// ll v = cur_v * g(r) % p * p2[ clen - r] % p;
// assert(v == cont(1, r));
// add(res, v);
// break;
}
mul(cur_v, iw[ sid[j] ]);
if (cnt[ sid[j] ] > 1) {
clen -= cnt[ sid[j] ];
ll sc = cur_v;
mul(sc, p2[ cnt[sid[j]]-1 ] - 1);
int O = r - p1;
if (O > 0) {
ll v = sc * g(O) % p * p2[clen - O] % p;
////assert(v == cont(p1+1, r));
add(res, v);
}
clen += cnt[ sid[j] ];
}
int p2 = lst[r][ sid[j+1] ];
int L = r-p1+1, R = r-p2-1;
if (L <= R) {
ll v = (pf[R] - pf[L-1] + p) % p
* ::p2[clen - 1] % p;
add(res, v * cur_v);
}
}
if (nxt_c) {
++cnt[nxt_c];
swap(w[nxt_c], wb[nxt_c]);
swap(iw[nxt_c], iwb[nxt_c]);
}
}
if (res < 0) res += p;
cout << res << '\n';
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 21ms
memory: 14812kb
input:
3 2 1 2 2
output:
152
result:
ok answer is '152'
Test #2:
score: -100
Runtime Error
input:
4 3 1 2 1 2