蒟蒻求调
查看原帖
蒟蒻求调
236416
_stOrz_楼主2023/9/9 11:15
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 7e5 + 5;
const int M = 2e6 + 5;

int n, ans[N], tot, f[N], cnt, Y[N], gg;

struct node {
  int x, y, x_, y_, opt, id;
} g[N];

struct point {
  int x, y, a;
} upd[N];

namespace BIT {
  int c[N];
  
  void clear () { for (int i = 1; i <= gg; i ++) c[i] = 0; }
  
  int lowbit (int x) { return x & (-x); }
  
  void add (int x, int y) { for (; x <= gg; x += lowbit (x)) c[x] += y; }
  
  int ask (int x) { int ans = 0; for (; x; x -= lowbit (x)) ans += c[x]; return ans; }
  
  int Q (int l, int r) { return ask (r) - ask (l - 1); }
}

struct ASK {
  int l, x, y, id, ty;
} ask[N];



void CDQ (int l, int r) {
  if (l == r) return ;
  int mid = l + r >> 1, cntu = 0, cnta = 0; cnt = 0; gg = 0;
  for (int i = l; i <= mid; i ++)
    if (g[i].opt == 1) 
      Y[++ gg] = g[i].y, upd[++ cntu] = {g[i].x, g[i].y, g[i].x_};
  for (int i = mid + 1; i <= r; i ++) {
    if (g[i].opt == 2) {
     // f[++ cnt] = g[i].x, f[++ cnt] = g[i].x_;
      Y[++ gg] = g[i].y, Y[++ gg] = g[i].y_;
      ask[++ cnta] = {g[i].x - 1, g[i].y, g[i].y_, g[i].id, -1};
      ask[++ cnta] = {g[i].x_, g[i].y, g[i].y_, g[i].id, 1};
    }
  }
  //if (gg > N) { cout << "Fuck you\n"; exit (0); }
  BIT::clear ();
  sort (Y + 1, Y + gg + 1);
  for (int i = 1; i <= cntu; i ++)
    upd[i].y = lower_bound (Y + 1, Y + gg + 1, upd[i].y) - Y/*, cout << upd[i].y << " fuck\n"*/; 
  for (int i = 1; i <= cnta; i ++) {
    ask[i].x = lower_bound (Y + 1, Y + gg + 1, ask[i].x) - Y;
    ask[i].y = lower_bound (Y + 1, Y + gg + 1, ask[i].y) - Y;
   // cout << ask[i].x << " fuck " << ask[i].y << "\n";
  }

  //cout << "--------------------- \n" << l << " " << r << ": \n";
 // cout << cnt << "haha\n";
  sort (ask + 1, ask + cnta + 1, [] (ASK x, ASK y) {
    return x.l < y.l;
  });
  int R = 0;
  for (int i = 1; i <= cnta; i ++) {
    while (R < cntu and upd[R + 1].x <= ask[i].l) {
      ++ R; BIT::add (upd[R].y, upd[R].a);
     // cout << upd[R].y << " + " << upd[R].a << "\n";
    }
   // for (int i = 1; i <= cnt; i ++) cout << i << " : " << BIT::Q (1, cnt) << "; ";
    ans[ask[i].id] += ask[i].ty * BIT::Q (ask[i].x, ask[i].y);
    //cout << ask[i].id << " x: " << ask[i].x << " y: " << ask[i].y << " type: " << ask[i].ty << " " << BIT::Q (ask[i].x, ask[i].y) << "\n";
  }
  CDQ (l, mid); CDQ (mid + 1, r);
}

signed main () {
  int m, opt; cin >> opt >> m;
  while (1) {
    cin >> opt; if (opt == 3) break;
    if (opt == 1) {
      int x, y, a; cin >> x >> y >> a;
      ++ n;
      g[n] = { x, y, a, -114514, 1, n };
    }
    else {
      int x, y, x_, y_; cin >> x >> y >> x_ >> y_;
      ++ n;
      g[n] = { x, y, x_, y_, 2, ++ tot };
    }
  }
  CDQ (1, n);
  for (int i = 1; i <= tot; i ++) cout << ans[i] << "\n";
}

思路是CDQ+扫描线

2023/9/9 11:15
加载中...