QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#348966 | #8340. 3 Sum | ucup-team197# | TL | 263ms | 9340kb | C++20 | 7.7kb | 2024-03-09 22:41:11 | 2024-03-09 22:41:12 |
Judging History
answer
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math,inline")
#pragma GCC target("avx2")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<long long>;
using vvll = vector<vector<long long>>;
using vb = vector<bool>;
using i128 = __int128_t;
const int MAXK = 20'100;
const int D = 18;
const int S = MAXK / D;
const ll M = 1'000'000'000LL * 1'000'000'000;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
const ll MOD = 1e9 + 7;
ll pow10[D];
ll rnd[S];
void precomp() {
pow10[0] = 1;
for(int i = 1; i < D; i++) {
pow10[i] = 10 * pow10[i-1];
}
for(int i = 0; i < S; i++) {
rnd[i] = rng() % MOD;
}
}
struct BigInt {
ll num[S];
// vector<ll> num;
inline friend BigInt operator+(const BigInt &a, const BigInt &b) {
BigInt res;
int carry = 0;
for(int i = 0; i < S; i++) {
res.num[i] = carry + a.num[i] + b.num[i];
carry = 0;
if(res.num[i] >= M) {
res.num[i] -= M;
carry = 1;
}
}
return res;
}
inline void resolve_carry(int carry) {
for(int i = 0; i < S; i++) {
if(carry == 0) {
return;
}
num[i] += carry;
carry = 0;
if(num[i] >= M) {
num[i] -= M;
carry = 1;
}
}
}
inline friend BigInt inegate(const BigInt &a, int k) {
BigInt res;
for(int i = 0; i < S; i++) {
if(i * D > k) break;
ll limit = M;
if((i+1) * D > k) [[unlikely]]{
limit = pow10[k - i * D];
}
res.num[i] = limit - 1 - a.num[i];
}
res.norm(k);
return res;
}
inline friend BigInt plusmod(const BigInt &a, const BigInt &b, int k) {
BigInt c = a + b;
c.norm(k);
return c;
}
inline void norm(int k) {
int big = k / D;
int idx = k % D;
if(num[big] >= pow10[idx]) [[unlikely]] {
num[big] -= pow10[idx];
for(int i = 0; i < S; i++) {
num[i] += 1;
if(num[i] >= M) [[likely]] {
num[i] = 0;
} else {
break;
}
}
}
for(int i = 0; i < S; i++) {
if(i * D > k) break;
ll limit = M;
if((i+1) * D > k) [[unlikely]]{
limit = pow10[k - i * D];
}
if(num[i] != limit-1) {
return;
}
}
memset(num, 0, sizeof(num));
}
inline void add_digit(int d, int pos, int k, int &spill) {
int big = pos / D;
int idx = pos % D;
num[big] += pow10[idx] * d;
for(int i = big; i < S; i++) {
if(i * D > k) break;
ll limit = M;
bool end = (i+1) * D > k;
if(end) [[unlikely]]{
limit = pow10[k - i * D];
}
if(num[i] >= limit) [[likely]] {
if(end) {
num[i] -= limit;
spill++;
} else {
num[i] -= M;
num[i+1]++;
}
} else {
break;
}
}
}
ll hash() {
ll result = 0;
for(int i = 0; i+4 < S; i+=4) {
result = (result + rnd[i] * num[i] + rnd[i+1] * num[i+1] + rnd[i+2] * num[i+2] + rnd[i+3] * num[i+3]) % MOD;
}
return result;
}
};
void solve(){
ll n;
int k;
cin >> n >> k;
vector<BigInt> nums;
for(int i = 0; i < n; i++) {
// cerr << i << endl;
string s;
cin >> s;
reverse(s.begin(), s.end());
int len = s.size();
BigInt t;
memset(t.num, 0, sizeof(t.num));
vi carry(S);
int spill = 0;
for(int i = 0; i < len; i++) {
// cerr << i << endl;
t.add_digit(s[i]-'0', i % k, k, spill);
// int g = i % k;
// int big = g / D;
// int small = g % D;
// t.num[big] += pow10[small] * (s[i]-'0');
// if((big+1) * D > k) [[unlikely]] {
// ll limit = pow10[((len-1) % D) + 1];
// if(t.num[big] >= limit) {
// t.num[big] -= limit;
// of++;
// }
// } else {
// if(t.num[big] >= M) {
// t.num[big] -= M;
// carry[big]++;
// }
// }
// }
// int c = 0;
// for(int i = 0; i < S; i++) {
// if((i+1) * D > k) {
// t.num[i] += carry[i] + c;
// ll limit = pow10[((len-1) % D) + 1];
// if(t.num[i] >= limit) of++;
// break;
// }
// t.num[i] += carry[i] + c;
// if(t.num[i] > M) {
// c++;
// }
}
// cerr << of << endl;
t.resolve_carry(spill);
t.norm(k);
nums.push_back(t);
}
BigInt lim;
memset(lim.num, 0, sizeof(lim.num));
for(int i = 0; i < S; i++) {
if(i * D > k) break;
ll limit = M;
if((i+1) * D > k) [[unlikely]]{
limit = pow10[k - i * D];
}
lim.num[i] = limit - 1;
}
// for(int i = 0; i < 10; i++) {
// for(int j = 0; j < 4; j++) {
// cout << nums[i].num[j] << ' ';
// }
// cout << endl;
// }
vll nh;
vll nh2;
map<ll, int> negate_hash;
for(int i = 0; i < n; i++) {
BigInt neg = inegate(nums[i], k);
// cerr << neg.num[0] << endl;
ll h = neg.hash();
ll h2 = (neg + lim).hash();
nh.push_back(h);
nh2.push_back(h2);
negate_hash[h]++;
negate_hash[h2]++;
}
int ans = 0;
int alldiff = 0;
int allsame = 0;
int twosame = 0;
for(int i = 0; i < n; i++) {
for(int j = i; j < n; j++) {
// cerr << i << ' ' << j << endl;
// BigInt res = plusmod(nums[i], nums[j], k);
BigInt res = nums[i] + nums[j];
ll hsh = res.hash();
// ll hsh = rng() % 10;
int tot = 0;
if(negate_hash.find(hsh) != negate_hash.end()) {
tot = negate_hash[hsh];
}
int same = (nh[i] == hsh || nh2[i] == hsh) + ( (nh[j] == hsh || nh2[j] == hsh) && i != j);
int diff = tot - same;
alldiff += diff * (i != j) * 2;
twosame += diff * (i == j) * 2 + same * (i != j);
allsame += same * (i == j);
// cerr << i << ' ' << j << ' ' << res.num[0] << ' ' << (negate_hash[hsh] - (nh[i] == hsh) - (i != j && nh[j] == hsh)) * (i == j ? 1 : 2) << endl;
// ans += (negate_hash[hsh] - (nh[i] == hsh) - (nh[j] == hsh)) * (i == j ? 1 : 2);
// int pz = negate_hash[hsh] - (nh[i] == hsh) - (i != j && nh[j] == hsh);
// cerr << i << ' ' << j << ' ' << pz << endl;
// ans += (i == j) ? pz * 2 : pz;
}
}
// cerr << alldiff << ' ' << twosame << ' ' << allsame << endl;
cout << alldiff / 6 + twosame / 6 + allsame << endl;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
precomp();
solve();
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3932kb
input:
4 1 0 1 10 17
output:
3
result:
ok 1 number(s): "3"
Test #2:
score: 0
Accepted
time: 263ms
memory: 9340kb
input:
500 859 7118711592236878297922359501613604144948355616986970837340677671376753603836852811886591300370143151943368529129749813118476151865844255212534355441611481420938483178075143062691345257288242460282715389758789648541099090735875617822348551942134616963557723055980260082230902505269975518146286...
output:
0
result:
ok 1 number(s): "0"
Test #3:
score: -100
Time Limit Exceeded
input:
500 17336 11871159223687829792235950161360414494835561698697083734067767137675360383685281188659130037014315194336852912974981311847615186584425521253435544161148142093848317807514306269134525728824246028271538975878964854109909073587561782234855194213461696355772305598026008223090250526997551814628...