QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#296353#4813. DS Team Selectionucup-team087#WA 7ms4096kbC++148.5kb2024-01-02 19:53:482024-01-02 19:53:48

Judging History

你现在查看的是最新测评结果

  • [2024-01-02 19:53:48]
  • 评测
  • 测评结果:WA
  • 用时:7ms
  • 内存:4096kb
  • [2024-01-02 19:53:48]
  • 提交

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;
}

詳細信息

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'