QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#525332#1823. Permutation CFGRngBased#TL 1ms5668kbC++174.4kb2024-08-20 15:36:082024-08-20 15:36:09

Judging History

你现在查看的是最新测评结果

  • [2024-08-20 15:36:09]
  • 评测
  • 测评结果:TL
  • 用时:1ms
  • 内存:5668kb
  • [2024-08-20 15:36:08]
  • 提交

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++]);
                assert(idx[i] <= 200);
                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: 1ms
memory: 5668kb

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...

output:


result: