QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#280509#7789. Outro: True Love Waitsucup-team1516#WA 4ms11372kbC++177.0kb2023-12-09 16:34:332023-12-09 16:34:34

Judging History

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

  • [2023-12-09 16:34:34]
  • 评测
  • 测评结果:WA
  • 用时:4ms
  • 内存:11372kb
  • [2023-12-09 16:34:33]
  • 提交

answer

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

template <int mod>
struct static_modint {
    using mint = static_modint;
    int x;

    static_modint() : x(0) {}
    static_modint(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

    mint& operator+=(const mint& rhs) {
        if ((x += rhs.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        if ((x += mod - rhs.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        x = (int) (1LL * x * rhs.x % mod);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint pow(long long n) const {
        mint _x = *this, r = 1;
        while (n) {
            if (n & 1) r *= _x;
            _x *= _x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const { return pow(mod - 2); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }
    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs.x == rhs.x;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs.x != rhs.x;
    }

    friend ostream &operator<<(ostream &os, const mint &p) {
        return os << p.x;
    }
    friend istream &operator>>(istream &is, mint &a) {
        int64_t t; is >> t;
        a = static_modint<mod>(t);
        return (is);
    }
};

const unsigned int mod = 1e9+7;
using modint = static_modint<mod>;
modint mod_pow(ll n, ll x) { return modint(n).pow(x); }
modint mod_pow(modint n, ll x) { return n.pow(x); }

template<class T>
struct Mat{
    vector<vector<T>> A;
    Mat(){}
    Mat(size_t n,size_t m):A(n,vector<T>(m,0)){}
    Mat(size_t n):A(n,vector<T>(n,0)){};
    size_t height() const{
        return A.size();
    }
    size_t width() const{
        return A[0].size();
    }
    inline const vector<T> &operator[](int k) const{
        return A.at(k);
    }
    inline vector<T> &operator[](int k){
        return A.at(k);
    }
    static Mat I(size_t n){
        Mat mat(n);
        for(int i=0;i<n;i++){
            mat[i][i]=1;
        }
        return mat;
    }
    Mat &operator+=(const Mat &B){
        size_t n=height(),m=width();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                (*this)[i][j]=(*this)[i][j]+B[i][j];
            }
        }
        return (*this);
    }
    Mat &operator-=(const Mat &B){
        size_t n=height(),m=width();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                (*this)[i][j]=(*this)[i][j]-B[i][j];
            }
        }
        return (*this);
    }
    Mat &operator*=(const Mat &B){
        int n=height(),m=B.width(),p=width();
        assert(p==B.height());
        vector<vector<T>> C(n,vector<T>(m,0));
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                for(int k=0;k<p;k++){
                    C[i][j] += (*this)[i][k]*B[k][j];
                }
            }
        }
        A.swap(C);
        return (*this);
    }
    Mat &operator^=(ll k){
        Mat B=Mat::I(height());
        while(k){
            if(k%2)B*=(*this);
            (*this)*=(*this);
            k>>=1LL;
        }
        A.swap(B.A);
        return (*this);
    }
    Mat operator+(const Mat &B) const{
        return (Mat(*this)+=B);
    }
    Mat operator-(const Mat &B) const{
        return (Mat(*this)-=B);
    }
    Mat operator*(const Mat &B) const{
        return (Mat(*this)*=B);
    }
    Mat operator^(const Mat &B) const{
        return (Mat(*this)^=B);
    }
};

const int N = 1000100;
modint pcal[N]; // pcal[i] : i番目に0を作るのに必要な操作回数
modint psum[N];

void debug() {
    set<pair<int,int>> st;
    const int n = 1000; // 試行回数の上限
    const int bit = 6; // ビット数(< 30)
    int cur = 0;
    for (int i = 0; i < n; ++i) {
        printf("%03d: ", i);
        cout << bitset<bit>(cur) << endl;
        bool ok = false;
        for (int j = 0; j < bit; ++j) {
            int nxt = cur^(1<<j);
            if (st.find({cur, nxt}) == st.end()) {
                st.insert({cur, nxt});
                st.insert({nxt, cur});
                cur = nxt;
                ok = true;
                break;
            }
        }
        if (!ok) break;
    }
}

modint slv_0(int K) {
    Mat<modint> A = Mat<modint>(3, 3);
    A[0][1] = 3, A[0][2] = 4, A[1][0] = 0, A[1][1] = 4, A[1][2] = 4, A[2][2] = 1;
    Mat<modint> B(3, 1);
    B[2][0] = 1;
    A ^= (K-1);
    return (A*B)[1][0];
}

void slv(int n, vector<bool> &bit, int K) {
    modint res = 0;
    int sum = 0;
    for (int i = n-2; i >= 0; i -= 2) {
        if (!bit[i] and !bit[i+1]) {
            sum += 1;
            continue;
        }
        int id = i/2;
        sum = 0;
        res += psum[id];
        if (bit[i] and !bit[i+1]) {
            res += 1;
        }
        else if (bit[i] and bit[i+1]) {
            res += 1 + psum[id] + 1;
        }
        else {
            res += 1 + psum[id] + 1 + psum[id] + 1;
        }
    }
    if (K > sum + 1) {
        cout << -1 << "\n";
        return;
    }
    res += slv_0(K);
    cout << res << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
//    debug();
    for (int i = 1; i < N; ++i) {
        pcal[i] = (pcal[i-1]+1)*3 + 1;
        psum[i] = pcal[i] + psum[i-1];
//        if (i < 10) {
//            cout << pcal[i] << " " << psum[i] << endl;
//        }
    }

    int q; cin >> q;
    while (q--) {
        string s,t; cin >> s >> t;
        reverse(s.begin(), s.end());
        reverse(t.begin(), t.end());
        int K; cin >> K;
        int len = max(s.size(), t.size());
        if (len%2) len += 1;
        vector<bool> bit(len);
        bool zero = true;
        for (int i = 0; i < len; ++i) {
            int ss = 0, tt = 0;
            if (i < s.size()) ss = s[i]-'0';
            if (i < t.size()) tt = t[i]-'0';
            ss ^= tt;
            bit[i] = ss;
            if (ss) zero = false;
        }

        if (zero) cout << slv_0(K) << "\n";
        else slv(len, bit, K);
    }
}

详细

Test #1:

score: 100
Accepted
time: 4ms
memory: 11332kb

input:

4
1 10 1
1 10 2
100 0 2
11 11 3

output:

2
-1
9
20

result:

ok 4 number(s): "2 -1 9 20"

Test #2:

score: 0
Accepted
time: 4ms
memory: 11332kb

input:

1
0 0 1

output:

0

result:

ok 1 number(s): "0"

Test #3:

score: 0
Accepted
time: 4ms
memory: 11372kb

input:

100
110111 11111 1
10110 101101 1
11010 111111 1
100110 1 1
10010 11010 1
1100 10111 1
100100 111110 1
101110 101100 1
1011 10110 1
110100 1110 1
11010 11000 1
11110 1000 1
111000 11101 1
110 1001 1
101010 11000 1
10 111110 1
110001 101000 1
1010 1000 1
10101 11 1
111011 11010 1
110001 100000 1
1100...

output:

78
59
69
70
15
38
39
3
32
60
3
29
69
12
45
52
37
3
29
64
22
39
54
69
65
27
33
76
34
18
57
13
81
15
23
70
69
36
18
23
29
42
69
54
6
0
63
3
29
15
10
16
80
24
37
59
71
13
23
31
21
34
23
48
21
47
7
44
42
3
37
75
59
29
55
39
29
28
29
70
55
16
54
47
24
18
79
60
8
26
64
58
32
6
8
37
2
68
42
44

result:

ok 100 numbers

Test #4:

score: -100
Wrong Answer
time: 4ms
memory: 11332kb

input:

100
10011111 111 2
1011101100 1000000100 1
100011111 1001001111 1
1001100101 1100100001 1
10101000 10000100 1
1011110101 100011101 1
110100001 111011010 1
1101001100 1111101101 1
1001101 11011010 1
1101110110 1101011000 1
110011001 1100001111 2
1001111001 1011001111 1
1001110 1101110100 2
1110110100...

output:

259
224
560
311
73
690
132
283
247
76
-1
269
-1
-1
74
-1
276
257
933
313
843
0
644
711
867
444
-1
796
379
583
624
697
962
298
394
622
-1
327
855
890
633
-1
-1
795
772
318
122
251
80
524
733
536
31
698
769
913
506
211
744
636
384
685
984
330
758
237
-1
808
717
501
-1
152
-1
11
570
311
873
763
541
401...

result:

wrong answer 1st numbers differ - expected: '295', found: '259'