QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#296353 | #4813. DS Team Selection | ucup-team087# | WA | 7ms | 4096kb | C++14 | 8.5kb | 2024-01-02 19:53:48 | 2024-01-02 19:53:48 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
// add X^x Y^y (1-X)^-(a+1) (1-Y)^-(b+1)
// get [X^x Y^y]
// [X^x' Y^y'] X^x Y^y (1-X)^-(a+1) (1-Y)^-(b+1)
// = [x<=x'] [y<=y'] binom(x'-x+a,a) binom(y'-y+b,b)
// = [x<=x'] [y<=y'] (x'+1-x)^(rise a)/a! (y'+1-y)^(rise b)/b!
// = [x<=x'] [y<=y'] \sum[0<=a'<=a] \sum[0<=b'<=b] (x'+1)^(rise a')/a'! (-x)^(rise a-a')/(a-a')! (y'+1)^(rise b')/b'! (-y)^(rise b-b')/(b-b')!
template <class X, class Y, class T, int A, int B> struct StaticAddRectSum {
// x^(rise a)/a!, y^(rise b)/b!
T xRise[A + 1], yRise[B + 1];
void riseX(int a, X x) {
static_assert(0 <= A); static_assert(A <= 4);
assert(0 <= a); assert(a <= A);
xRise[0] = 1;
if (a == 0) return;
X x0 = x;
xRise[1] = T(x0);
if (a == 1) return;
X x1 = x + 1;
((x0 % 2 == 0) ? x0 : x1) /= 2;
xRise[2] = T(x0) * T(x1);
if (a == 2) return;
X x2 = x + 2;
((x0 % 3 == 0) ? x0 : (x1 % 3 == 0) ? x1 : x2) /= 3;
xRise[3] = T(x0) * T(x1) * T(x2);
if (a == 3) return;
X x3 = x + 3;
((x0 % 2 == 0) ? x0 : (x1 % 2 == 0) ? x1 : (x2 % 2 == 0) ? x2 : x3) /= 2;
((x0 % 2 == 0) ? x0 : (x1 % 2 == 0) ? x1 : (x2 % 2 == 0) ? x2 : x3) /= 2;
xRise[4] = T(x0) * T(x1) * T(x2) * T(x3);
}
void riseY(int b, Y y) {
static_assert(0 <= B); static_assert(B <= 4);
assert(0 <= b); assert(b <= B);
yRise[0] = 1;
if (b == 0) return;
Y y0 = y;
yRise[1] = T(y0);
if (b == 1) return;
Y y1 = y + 1;
((y0 % 2 == 0) ? y0 : y1) /= 2;
yRise[2] = T(y0) * T(y1);
if (b == 2) return;
Y y2 = y + 2;
((y0 % 3 == 0) ? y0 : (y1 % 3 == 0) ? y1 : y2) /= 3;
yRise[3] = T(y0) * T(y1) * T(y2);
if (b == 3) return;
Y y3 = y + 3;
((y0 % 2 == 0) ? y0 : (y1 % 2 == 0) ? y1 : (y2 % 2 == 0) ? y2 : y3) /= 2;
((y0 % 2 == 0) ? y0 : (y1 % 2 == 0) ? y1 : (y2 % 2 == 0) ? y2 : y3) /= 2;
yRise[4] = T(y0) * T(y1) * T(y2) * T(y3);
}
struct QueryAdd {
int a, b;
X x;
Y y;
T val;
};
struct QueryGet {
X x;
Y y;
};
vector<QueryAdd> qsAdd;
vector<QueryGet> qsGet;
vector<T> anss;
void add(int a, int b, X x, Y y, T val) {
assert(0 <= a); assert(a <= A);
assert(0 <= b); assert(b <= B);
qsAdd.push_back(QueryAdd{a, b, x, y, val});
}
void get(X x, Y y) {
qsGet.push_back(QueryGet{x, y});
}
struct Array {
T t[A + 1][B + 1];
Array() : t{} {}
};
void run() {
const int qsAddLen = qsAdd.size(), qsGetLen = qsGet.size();
vector<pair<X, int>> events(qsAddLen + qsGetLen);
for (int i = 0; i < qsAddLen; ++i) events[i] = std::make_pair(qsAdd[i].x, i);
for (int j = 0; j < qsGetLen; ++j) events[qsAddLen + j] = std::make_pair(qsGet[j].x, qsAddLen + j);
std::sort(events.begin(), events.end());
vector<Y> ys(qsAddLen);
for (int i = 0; i < qsAddLen; ++i) ys[i] = qsAdd[i].y;
std::sort(ys.begin(), ys.end());
ys.erase(std::unique(ys.begin(), ys.end()), ys.end());
const int ysLen = ys.size();
vector<Array> bit(ysLen);
anss.assign(qsGetLen, 0);
for (const auto &event : events) {
if (event.second < qsAddLen) {
const int i = event.second;
const QueryAdd &q = qsAdd[i];
riseX(q.a, -q.x);
riseY(q.b, -q.y);
T val[A + 1][B + 1];
for (int a = 0; a <= q.a; ++a) for (int b = 0; b <= q.b; ++b) val[a][b] = q.val * xRise[q.a - a] * yRise[q.b - b];
for (int l = std::lower_bound(ys.begin(), ys.end(), q.y) - ys.begin(); l < ysLen; l |= l + 1) {
for (int a = 0; a <= q.a; ++a) for (int b = 0; b <= q.b; ++b) bit[l].t[a][b] += val[a][b];
}
} else {
const int j = event.second - qsAddLen;
const QueryGet &q = qsGet[j];
riseX(A, q.x + 1);
riseY(B, q.y + 1);
T sum[A + 1][B + 1] = {};
for (int l = std::upper_bound(ys.begin(), ys.end(), q.y) - ys.begin(); l > 0; l &= l - 1) {
for (int a = 0; a <= A; ++a) for (int b = 0; b <= B; ++b) sum[a][b] += bit[l - 1].t[a][b];
}
for (int a = 0; a <= A; ++a) for (int b = 0; b <= B; ++b) anss[j] += sum[a][b] * xRise[a] * yRise[b];
}
}
}
};
////////////////////////////////////////////////////////////////////////////////
int M;
vector<int> O;
vector<int> X[2], Y[2], D;
vector<unsigned> W;
vector<unsigned> ans;
void solve(int mL, int mR) {
if (mR - mL >= 2) {
const int mMid = (mL + mR) / 2;
solve(mL, mMid);
solve(mMid, mR);
StaticAddRectSum<int, int, unsigned, 3, 1> f;
StaticAddRectSum<int, int, unsigned, 3, 0> g, h;
for (int m = mL; m < mMid; ++m) if (O[m] == 1) {
/*
11111
12221
12321
12221
11111
*= (1-X)(1-Y)
+ -
+ -
+-
-+
- +
- +
Apart[]
+1 / (1-X)^2(1-Y)^2(1-XY)
= + 1 / (1-X)^3(1-Y)^2 - X / (1-X)^4(1-Y) + X^2 / (1-X)^4(1-XY)
-1 / (1-X)^2(1-Y)^2(1-XY^-1)
= - 1 / (1-X)^3(1-Y)^2 - X / (1-X)^4(1-Y) - XY^-1 / (1-X)^4(1-XY^-1)
X^x Y^y = X^(x-y) (XY)^y
X^x Y^y = X^(x+y) (XY^-1)^-y
*/
const int x0 = X[0][m] - D[m] + 1, x1 = X[0][m] + D[m];
const int y0 = Y[0][m] - D[m] + 1, y1 = Y[0][m] + D[m];
// cerr<<"m = "<<m<<": "<<make_pair(x0,y0)<<" "<<make_pair(x1+1,y1+1)<<"; "<<make_pair(x0,y1)<<" "<<make_pair(x1+1,y0-1)<<endl;
f.add(2, 1, x0, y0, +W[m]);
f.add(2, 1, (x1+1), (y1+1), -W[m]);
f.add(3, 0, x0 + 1, y0, -W[m]);
f.add(3, 0, (x1+1) + 1, (y1+1), +W[m]);
g.add(3, 0, x0 - y0 + 2, y0, +W[m]);
g.add(3, 0, (x1+1) - (y1+1) + 2, (y1+1), -W[m]);
f.add(2, 1, x0, y1, -W[m]);
f.add(2, 1, (x1+1), (y0-1), +W[m]);
f.add(3, 0, x0 + 1, y1, -W[m]);
f.add(3, 0, (x1+1) + 1, (y0-1), +W[m]);
h.add(3, 0, x0 + y1, -y1 + 1, -W[m]);
h.add(3, 0, (x1+1) + (y0-1), -(y0-1) + 1, +W[m]);
}
for (int m = mMid; m < mR; ++m) if (O[m] == 2) {
for (int s = 0; s < 2; ++s) for (int t = 0; t < 2; ++t) {
f.get(X[s][m], Y[t][m]);
g.get(X[s][m] - Y[t][m], Y[t][m]);
h.get(X[s][m] + Y[t][m], -Y[t][m]);
}
}
f.run();
g.run();
h.run();
// cerr<<"f.anss = "<<f.anss<<endl;
// cerr<<"g.anss = "<<g.anss<<endl;
// cerr<<"h.anss = "<<h.anss<<endl;
int j = 0;
for (int m = mMid; m < mR; ++m) if (O[m] == 2) {
for (int s = 0; s < 2; ++s) for (int t = 0; t < 2; ++t) {
ans[m] += ((s ^ t) ? -1 : +1) * (f.anss[j] + g.anss[j] + h.anss[j]);
++j;
}
}
}
}
int main() {
for (; ~scanf("%d", &M); ) {
O.assign(M, 0);
for (int s = 0; s < 2; ++s) {
X[s].assign(M, 0);
Y[s].assign(M, 0);
}
D.assign(M, 0);
W.assign(M, 0);
for (int m = 0; m < M; ++m) {
scanf("%d", &O[m]);
if (O[m] == 1) {
scanf("%d%d%d%u", &X[0][m], &Y[0][m], &D[m], &W[m]);
} else if (O[m] == 2) {
scanf("%d%d%d%u", &X[0][m], &X[1][m], &Y[0][m], &Y[1][m]);
--X[0][m];
--Y[0][m];
} else {
assert(false);
}
}
ans.assign(M, 0);
solve(0, M);
for (int m = 0; m < M; ++m) if (O[m] == 2) {
printf("%u\n", ans[m]);
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 4096kb
input:
4 1 3 4 5 1 2 1 4 3 5 1 2 4 2 2 2 4 5 3 5
output:
46 21
result:
ok 2 number(s): "46 21"
Test #2:
score: -100
Wrong Answer
time: 7ms
memory: 4056kb
input:
998 2 551 711 262 646 2 128 467 106 519 1 558 927 450 66595084 1 361 809 208 60332548 1 515 957 618 80796575 2 284 931 117 684 1 896 611 247 70974392 1 11 714 426 87481360 2 881 968 136 697 1 454 562 451 86471007 1 101 439 155 51776388 2 2 672 46 246 1 524 268 227 93245818 2 223 697 669 757 1 162 72...
output:
0 0 4086348824 1146488212 1923814220 798324882 2921887262 1290265609 3513219844 3474084352 3854449873 4244389487 3074750329 3926160295 3834449026 1400315986 1104863194 2313328922 710425585 4229652587 3699635176 774115858 81820823 2102567368 3457426400 3191526911 2168807999 1182604382 3501121072 2518...
result:
wrong answer 3rd numbers differ - expected: '865123352', found: '4086348824'