提出 #74391491


ソースコード 拡げる

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define all(p) p.begin(),p.end()

struct FastSet {
    using u64 = u_int64_t;
    static constexpr u64 B = 64;
    u64 size;
    vector<vector<u64>> a;
    FastSet(u64 n) : size(n) {
        do a.emplace_back(n = (n + B - 1) / B);
        while(n > 1);
    }
    bool operator[](int i) { return a[0][i / B] >> (i % B) & 1; }
    void set(int i) {
        for(auto& v : a) {
            v[i / B] |= 1ULL << (i % B);
            i /= B;
        }
    }
    void reset(ll i) {
        for(auto& v : a) {
            v[i / B] &= ~(1ULL << (i % B));
            if(v[i / B]) break;
            i /= B;
        }
    }
    int next(int i) {  // i を超える最⼩の要素
        for (int h = 0; h < (int)a.size(); h++) {
            i++;
            if(i / B >= (int)a[h].size()) break;
            u64 d = a[h][i / B] >> (i % B);
            if(d) {
                i += countr_zero(d);
                while(h--) i = i * B + countr_zero(a[h][i]);
                return i;
            }
            i /= B;
        }
        return size;
    }
    int prev(int i) {  // i より小さい最⼤の要素
        for (int h = 0; h < (int)a.size(); h++) {
            i--;
            if(i < 0) break;
            u64 d = a[h][i / B] << (~i % B);
            if(d) {
                i -= countl_zero(d);
                while(h--) i = i * B + __lg(a[h][i]);
                return i;
            }
            i /= B;
        }
        return -1;
    }
};

// https://qiita.com/keymoon/items/11fac5627672a6d6a9f6
namespace po167{
    struct mint61{
        using u64 = unsigned long long;
        static constexpr u64 MOD = (1ULL << 61) - 1;
        static constexpr u64 MASK30 = (1ULL << 30) - 1;
        static constexpr u64 MASK31 = (1ULL << 31) - 1;
        u64  x;
        u64 calcmod(u64 a){
            u64 au = (a >> 61);
            u64 ad = (a & MOD);
            u64 res = au + ad;
            if (res >= MOD) res -= MOD;
            return res;
        }
        mint61(){ x = 0;}
        mint61(long long x_){
            while (x_ < 0) x_ += MOD;
            x = calcmod(x_);
        }
        mint61 &operator+=(mint61 b){
            if ((x += b.x) >= MOD) x -= MOD;
            return *this;
        }
        mint61 &operator-=(mint61 b){
            if (x >= b.x) x -= b.x;
            else{
                x += MOD;
                x -= b.x;
            }
            return *this;
        }
        mint61 &operator*=(mint61 b){
            u64 au = (x >> 31);
            u64 ad = (x & MASK31);
            u64 bu = (b.x >> 31);
            u64 bd = (b.x & MASK31);
            u64 mid = ad * bu + au * bd;
            u64 midu = (mid >> 30);
            u64 midd = (mid & MASK30);
            x = calcmod(au * bu * 2 + midu + (midd << 31) + ad * bd);
            return *this;
        }
        friend mint61 operator+(mint61 a, mint61 b){return a += b;}
        friend mint61 operator-(mint61 a, mint61 b){return a -= b;}
        friend mint61 operator*(mint61 a, mint61 b){return a *= b;}
        friend bool operator==(mint61 a, mint61 b){return a.x == b.x;}
        friend bool operator!=(mint61 a, mint61 b){return a.x != b.x;}
        mint61 pow(long long e) const {
            mint61 r = 1,b =*this;
            if (e < 0) e = MOD - 1 + e % (MOD - 1);
            while (e){
                if (e & 1) r *= b;
                b *= b;
                e >>= 1;
            }
            return r;
        }
    };
}

using mint = po167::mint61;

random_device seed_gen;
mt19937 rng(seed_gen());
// return [l, r)
long long rand_long(long long l,long long r){
    return uniform_int_distribution<long long>(l,r-1)(rng);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    vector<int> A(N);
    rep(i, 0, N) cin >> A[i];
    const int L = 200'200;
    FastSet fs(L);
    ll ans = 0;
    vector<mint> z(L);
    rep(i, 0, L) z[i] = rand_long(1, mint::MOD);
    vector<mint> z_sum(L);
    rep(i, 0, L - 1) z_sum[i + 1] = z_sum[i] + z[i];
    auto g = [&](int st, int en) -> tuple<vector<mint::u64>, vector<mint::u64>, vector<int>> {
        mint sum = 0;
        vector<mint::u64> real, small;
        int d = 1;
        vector<int> same;
        if (st > en) d = -1;
        for (int i = st; i != en + d; i += d){
            int a = A[i];
            while (fs[a]){
                fs.reset(a);
                sum -= z[a];
                a++;
            }
            fs.set(a);
            sum += z[a];
            real.push_back(sum.x);
            int l = fs.next(-1);
            int r = fs.prev(L);
            if (l == r) same.push_back(l);
            else small.push_back((z_sum[r + 1] - sum - z_sum[l] + z[l]).x);
        }
        while (true){
            int tmp = fs.next(-1);
            if (tmp == fs.size) break;
            fs.reset(tmp);
        }
        return {real, small, same};
    };
    auto h = [&](vector<auto> X, vector<auto> Y) -> ll {
        sort(all(X));
        sort(all(Y));
        int a = 0, b = 0;
        ll res = 0;
        while (a != (int)X.size() && b != (int)Y.size()){
            if (X[a] < Y[b]) a++;
            else if (X[a] > Y[b]) b++;
            else{
                int tmp = 0;
                while (a + tmp != (int)X.size() && X[a + tmp] == X[a]){
                    tmp++;
                }
                while (b != (int)Y.size() && X[a] == Y[b]){
                    b++;
                    res += tmp;
                }
                a += tmp;
            }
        }
        return res;
    };
    auto calc = [&](auto self, int l, int r) -> void {
        if (l + 1 == r){
            ans++;
            return;
        }
        int m = (l + r) / 2;
        self(self, l, m);
        self(self, m, r);
        auto [L_real, L_small, L_same] = g(m - 1, l);
        auto [R_real, R_small, R_same] = g(m, r - 1);
        ans += h(L_real, R_small);
        ans += h(L_small, R_real);
        ans += h(L_same, R_same);
    };
    calc(calc, 0, N);
    cout << ans << "\n";
}

提出情報

提出日時
問題 C - Count Power of 2
ユーザ potato167
言語 C++ IOI-Style(GNU++20) (GCC 14.2.0)
得点 800
コード長 6350 Byte
結果 AC
実行時間 466 ms
メモリ 11512 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 800 / 800
結果
AC × 3
AC × 51
セット名 テストケース
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
All 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_test_00.txt, 01_test_01.txt, 01_test_02.txt, 01_test_03.txt, 01_test_04.txt, 01_test_05.txt, 01_test_06.txt, 01_test_07.txt, 01_test_08.txt, 01_test_09.txt, 01_test_10.txt, 01_test_11.txt, 01_test_12.txt, 01_test_13.txt, 01_test_14.txt, 01_test_15.txt, 01_test_16.txt, 01_test_17.txt, 01_test_18.txt, 01_test_19.txt, 01_test_20.txt, 01_test_21.txt, 01_test_22.txt, 01_test_23.txt, 01_test_24.txt, 01_test_25.txt, 01_test_26.txt, 01_test_27.txt, 01_test_28.txt, 01_test_29.txt, 01_test_30.txt, 01_test_31.txt, 01_test_32.txt, 01_test_33.txt, 01_test_34.txt, 01_test_35.txt, 01_test_36.txt, 01_test_37.txt, 01_test_38.txt, 01_test_39.txt, 01_test_40.txt, 01_test_41.txt, 01_test_42.txt, 01_test_43.txt, 01_test_44.txt, 01_test_45.txt, 01_test_46.txt, 01_test_47.txt
ケース名 結果 実行時間 メモリ
00_sample_00.txt AC 4 ms 4844 KiB
00_sample_01.txt AC 4 ms 4844 KiB
00_sample_02.txt AC 4 ms 4844 KiB
01_test_00.txt AC 238 ms 8504 KiB
01_test_01.txt AC 308 ms 9056 KiB
01_test_02.txt AC 329 ms 9300 KiB
01_test_03.txt AC 271 ms 8772 KiB
01_test_04.txt AC 400 ms 9640 KiB
01_test_05.txt AC 458 ms 11132 KiB
01_test_06.txt AC 462 ms 11392 KiB
01_test_07.txt AC 456 ms 11132 KiB
01_test_08.txt AC 462 ms 11396 KiB
01_test_09.txt AC 463 ms 11128 KiB
01_test_10.txt AC 464 ms 11128 KiB
01_test_11.txt AC 460 ms 11136 KiB
01_test_12.txt AC 455 ms 11140 KiB
01_test_13.txt AC 461 ms 11116 KiB
01_test_14.txt AC 456 ms 11116 KiB
01_test_15.txt AC 455 ms 11112 KiB
01_test_16.txt AC 453 ms 11512 KiB
01_test_17.txt AC 455 ms 11112 KiB
01_test_18.txt AC 457 ms 11128 KiB
01_test_19.txt AC 462 ms 11136 KiB
01_test_20.txt AC 463 ms 11444 KiB
01_test_21.txt AC 462 ms 11132 KiB
01_test_22.txt AC 463 ms 11128 KiB
01_test_23.txt AC 461 ms 11116 KiB
01_test_24.txt AC 456 ms 11116 KiB
01_test_25.txt AC 445 ms 11116 KiB
01_test_26.txt AC 446 ms 11116 KiB
01_test_27.txt AC 451 ms 11112 KiB
01_test_28.txt AC 460 ms 11132 KiB
01_test_29.txt AC 460 ms 11392 KiB
01_test_30.txt AC 461 ms 11132 KiB
01_test_31.txt AC 466 ms 11124 KiB
01_test_32.txt AC 460 ms 11128 KiB
01_test_33.txt AC 459 ms 11124 KiB
01_test_34.txt AC 462 ms 11124 KiB
01_test_35.txt AC 459 ms 11124 KiB
01_test_36.txt AC 463 ms 11132 KiB
01_test_37.txt AC 369 ms 11116 KiB
01_test_38.txt AC 355 ms 11112 KiB
01_test_39.txt AC 424 ms 11116 KiB
01_test_40.txt AC 452 ms 11124 KiB
01_test_41.txt AC 456 ms 11124 KiB
01_test_42.txt AC 453 ms 11128 KiB
01_test_43.txt AC 451 ms 11124 KiB
01_test_44.txt AC 342 ms 11428 KiB
01_test_45.txt AC 363 ms 11112 KiB
01_test_46.txt AC 363 ms 11116 KiB
01_test_47.txt AC 4 ms 4844 KiB