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