一点疑惑
查看原帖
一点疑惑
88735
寒鸽儿楼主2021/9/13 19:08

下面的这份代码可以获得 85pts 的成绩。WA在了最后三个点。
但是把 muliset 和 数组 award( 用来记录奖励的剑的数组 ) 换成 long long,并修改对应的 inf 的值就过了。
不是很懂为什么,数据范围里写的攻击力 106\leq 10^6 的。
qaq。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define repp(i,a,b) for(int i=(a);i<(b);++i)
#define perr(i,a,b) for(int i=(a);i>(b);--i)

using namespace std;

typedef long long ll;

const int inf = 0x3f3f3f3f;

void exgcd( ll a, ll b, ll &x, ll &y, ll &g ) {
    if( b == 0 ) {
        g = a; x = 1; y = 0;
        return ;
    }
    exgcd( b, a % b, y, x, g );
    y -= a / b * x;
}

ll mulmod( ll x, ll y, ll mod ) {
    ll res = 0;
    ll f = y < 0 ? ( y = -y, -1 ) : 1;
    for( ; y; y >>= 1 ) {
        if( y & 1 ) res = ( res + x ) % mod;
        x = ( x + x ) % mod;
    }
    return f < 0 ? ( -res % mod + mod ) % mod : ( res % mod + mod ) % mod;
}

pair< ll, ll > excrt( vector< ll > &va, vector< ll > &vm ) {
    int n = vm.size(  );
    ll mi = vm[ 0 ], ai = ( va[ 0 ] % mi + mi ) % mi;
    ll ki, kj, g, L;
    for( int j = 1; j < n; ++ j ) {
        ll mj = vm[ j ], aj = ( va[ j ] % mj + mj ) % mj;
        exgcd( mi, -mj, ki, kj, g );
        // cout << mi << ' ' << mj << ' ' <<  __gcd( mi, mj ) << '\n';
        // cout << g << ' ' << aj - ai << '\n';
        if( ( aj - ai ) % g ) return { -1, -1 };
        L =  abs( mi / g * mj );
        ll x = mulmod( ki, ( aj - ai ) / g, L );
        ai = ( ai + mulmod( x, mi, L ) % L + L ) % L;
        mi = L;
    }
    return { ai, mi };
}

const int maxn = 1e5 + 10;
ll a[ maxn ], p[ maxn ], award[ maxn ];
multiset< ll > sword;

signed main (  ) {
    if( fopen( "yl.in", "r" ) ) {
        freopen( "yl.in", "r", stdin );
        freopen( "yl.out", "w", stdout );
    }
    ios::sync_with_stdio( false );
    cin.tie( NULL );
    int tests;
    cin >> tests;
    vector< ll > va, vm;
    rep( test,1,tests ) {
        int n, m;
        ll x, y, g, tmp;
        cin >> n >> m;
        va.clear(); vm.clear(); sword.clear();
        rep( i,1,n ) cin >> a[ i ];
        rep( i,1,n ) cin >> p[ i ];
        rep( i,1,n ) cin >> award[ i ];
        sword.insert( -inf ); sword.insert( inf );
        rep( i,1,m ) cin >> tmp, sword.insert( tmp );
        bool flg = true;
        ll xMin = 0;
        rep( i,1,n ) {
            auto it = sword.upper_bound( a[ i ] );
            -- it;
            if( *it == -inf ) ++ it;
            ll s = *it; sword.erase( it );
            exgcd( s, p[ i ], x, y, g );
            if( a[ i ] % g ) {
                flg = false;
                break;
            }
            s /= g; p[ i ] /= g; a[ i ] /= g;
            xMin = max( xMin, ( a[ i ] + s - 1 ) / s );
            x = ( x % p[ i ] + p[ i ] ) % p[ i ];
            vm.push_back( p[ i ] ); va.push_back( mulmod( a[ i ], x, p[ i ] ) );
            sword.insert( award[ i ] );
        }
        if( flg ) {
            pair< ll, ll > ret = excrt( va, vm );
            if( ret.first == -1 ) cout << "-1\n";
            else cout << ret.first + xMin / ret.second * ret.second << '\n';
        } else cout << "-1\n";
    }
    return 0;
}
2021/9/13 19:08
加载中...