QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#525321 | #1823. Permutation CFG | RngBased# | TL | 0ms | 5660kb | C++17 | 4.4kb | 2024-08-20 15:31:45 | 2024-08-20 15:31:45 |
Judging History
answer
#include <bits/stdc++.h>
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define F first
#define S second
#define all(x) x.begin(), x.end()
using namespace std;
const ll INF = 1e13;
int N, S, Q, p[100005], pos[100005], idx[100005];
ll ans[100005];
ll C(ll n, ll k)
{
if (k > n) return 0;
ll a = 1;
for (int i = 0; i < k; i++)
a = min(a * (n - i), INF);
for (int i = 1; i <= k; i++)
a /= i;
return a;
}
struct BIT
{
ll bit[100005];
void init()
{
fill(bit, bit + N + 1, 0);
}
void modify(int p, ll v)
{
for (; p <= N; p += (p & -p))
bit[p] += v;
}
ll query(int p)
{
ll a = 0;
for (; p; p -= (p & -p))
a += bit[p];
return a;
}
ll bsearch(ll v)
{
ll r = 0;
for (int p = (1 << __lg(N)); p >= 1; p >>= 1)
if (r + p <= N && bit[r + p] < v)
v -= bit[r + p], r += p;
return r;
}
} blen, bcnt, bacc;
/*
1 1 1 1
4 3 2 1
10 6 3 1
20 10 4 1
// s = 1: count number
// s = 2: count
// s >= 3: brute
*/
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> N >> S >> Q;
for (int i = 1; i <= N; i++)
cin >> p[i], pos[p[i]] = i;
// every query is in the form (n, pos, k, i)
vector<array<int, 4>> qu;
for (int i = 1; i <= Q; i++)
{
int len, k;
cin >> k >> len;
qu.emplace_back(array{N, k, len, i});
}
for (; S >= 1; S--)
{
vector<array<int, 4>> nqu;
sort(all(qu), [&](array<int, 4> a, array<int, 4> b) {return a[0] < b[0]; });
{
int nxt = 1;
blen.init();
for (auto &[n, k, len, i] : qu)
{
while (nxt <= n)
blen.modify(pos[nxt], C(nxt + S - 2, S - 1)), nxt++;
idx[i] = (int)blen.bsearch(len);
len -= blen.query(idx[i]);
}
}
if (S == 1)
{
for (auto &[n, k, pre, i] : qu)
ans[i]++;
}
else if (S == 2)
{
int nxt = 1;
bcnt.init();
for (auto &[n, k, pre, i] : qu)
{
while (nxt <= n)
bcnt.modify(pos[nxt++], 1);
ans[i] += bcnt.query(idx[i]);
}
sort(all(qu), [&](array<int, 4> a, array<int, 4> b) {return a[1] < b[1]; });
nxt = 1;
bcnt.init();
for (auto &[n, k, pre, i] : qu)
{
while (nxt < k)
bcnt.modify(pos[nxt++], 1);
ans[i] -= bcnt.query(idx[i]);
}
}
else if (S == 3)
{
int nxt = 1;
bcnt.init(), blen.init();
for (auto &[n, k, pre, i] : qu)
{
while (nxt <= n)
bcnt.modify(pos[nxt], 1), blen.modify(pos[nxt], nxt), nxt++;
ans[i] += blen.query(idx[i]) - bcnt.query(idx[i]) * (k - 1);
}
sort(all(qu), [&](array<int, 4> a, array<int, 4> b) {return a[1] < b[1]; });
nxt = 1;
bcnt.init(), blen.init();
for (auto &[n, k, pre, i] : qu)
{
while (nxt < k)
bcnt.modify(pos[nxt], 1), blen.modify(pos[nxt], nxt), nxt++;
ans[i] -= blen.query(idx[i]) - bcnt.query(idx[i]) * (k - 1);
}
}
else
{
int nxt = 1;
set<int> in;
for (auto &[n, k, pre, i] : qu)
{
while (nxt <= n)
in.insert(pos[nxt++]);
for (auto j : in)
if (j > idx[i]) break;
else
ans[i] += C(p[j] - k + S - 2, S - 2);
}
}
for (auto &[n, k, pre, i] : qu)
{
if (idx[i] == N || p[idx[i] + 1] < k)
continue;
else
{
tie(n, k, pre) = make_tuple(p[idx[i] + 1], k, pre);
nqu.emplace_back(array{n, k, pre, i});
}
}
nqu.swap(qu);
}
for (int i = 1; i <= Q; i++)
cout << ans[i] << '\n';
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 5660kb
input:
4 3 6 1 4 3 2 1 6 2 20 4 1 3 5 2 9 1 16
output:
3 6 0 1 2 8
result:
ok 6 numbers
Test #2:
score: -100
Time Limit Exceeded
input:
100000 5 200000 98129 52962 60307 83804 75634 55811 85666 40965 78529 40850 54600 83058 37001 92436 30323 54632 24238 77437 87162 75991 39863 74990 32168 99841 85430 66056 69893 7561 60704 40795 81535 89902 44331 20995 99461 93620 91817 97370 84025 98836 2455 77447 37078 90192 26249 84337 70311 4006...