QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#348852 | #8340. 3 Sum | ucup-team197# | TL | 1ms | 3668kb | C++20 | 6.1kb | 2024-03-09 21:49:52 | 2024-03-09 21:49:54 |
Judging History
answer
#pragma GCC optimize("unroll-loops")
#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];
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 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 big = pos / D;
int idx = pos % D;
num[big] += pow10[idx] * d;
for(int i = big; i < S; i++) {
if(num[i] >= M) [[likely]] {
num[i] -= M;
num[i+1]++;
} else {
break;
}
}
}
ll hash() {
ll result = 0;
for(int i = 0; i < S; i++) {
result = (result + rnd[i] * num[i]) % MOD;
}
return result;
}
};
void solve(){
ll n;
int k;
cin >> n >> k;
vector<BigInt> nums;
for(int i = 0; i < n; i++) {
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 of = 0;
for(int i = 0; i < len; i++) {
// cerr << i << endl;
t.add_digit(s[i]-'0', i % k, k);
// 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.norm(k);
nums.push_back(t);
}
// for(int i = 0; i < n; i++) {
// for(int j = 0; j < 4; j++) {
// cout << nums[i].num[j] << ' ';
// }
// cout << endl;
// }
vi nh;
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();
nh.push_back(h);
negate_hash[h]++;
}
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++) {
BigInt res = plusmod(nums[i], nums[j], k);
ll hsh = res.hash();
int tot = negate_hash[hsh];
int same = (nh[i] == hsh) + (nh[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: 3668kb
input:
4 1 0 1 10 17
output:
3
result:
ok 1 number(s): "3"
Test #2:
score: -100
Time Limit Exceeded
input:
500 859 7118711592236878297922359501613604144948355616986970837340677671376753603836852811886591300370143151943368529129749813118476151865844255212534355441611481420938483178075143062691345257288242460282715389758789648541099090735875617822348551942134616963557723055980260082230902505269975518146286...