动态开点线段树 MLE 求助
查看原帖
动态开点线段树 MLE 求助
207996
yzy1Ẽd<ßDream楼主2021/9/3 20:08

RT,我的做法和题解有些不同,不用离散化,直接把线段树改成动态开点的,但是这会导致 MLE,理论空间复杂度应该是正确的

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double lf;

#define rep(i, f, t) for (int i = (f), ed##i = (t); i <= ed##i; ++i)
#define re(i, t) rep (i, 1, t)
#define per(i, t, f) for (int i = (t), ed##i = (f); i >= ed##i; --i)
#define ste(i, f, t, s) for (int i = (f), ed##i = (t); i <= ed##i; i += s)
#define each(i, x) for (auto &i : (x))
#define nxt(i, f, g) for (int i = g.h[f]; i; i = g.e[i].n)
#define dbg(x) (cerr << "(dbg) " << #x " = " << (x) << '\n')
#define umod(x) ((x) >= mo && ((x) -= mo))
#define dmod(x) ((x) < 0 && ((x) += mo))
#define up(x, y) (((x) < (y)) && ((x) = (y)))
#define down(x, y) (((x) > (y)) && ((x) = (y)))
#define y1 y1__
#define fio(x) (freopen(x ".in", "r", stdin), freopen(x ".out", "w", stdout))

// clang-format off
namespace FastIO {
	const int SZ=(1<<21)+1;
	struct I {
		char ibuf[SZ],*iS,*iT,c;int f,_eof;FILE*fi;
		I(FILE*f):fi(f){}
		inline char Gc(){return iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SZ,fi),(iS==iT?EOF:*iS++)):*iS++;}
		inline ll operator()(){ll x;operator()(x);return x;}
		inline I&operator()(char&x){x=Gc();return*this;}
		inline I&operator()(char*s){for(c=Gc();c<32||c>126||c==' ';)c=Gc();for(;c>31&&c<127&&c!=' '&&c!='\n'&&c!='\r';++s,c=Gc())*s=c;*s=0;return*this;}
		template<class T>inline I&operator()(T&x){_eof=0;for(f=1,c=Gc();(c<'0'||c>'9')&&!_eof;c=Gc()){if(c=='-')f=-1;_eof|=c==EOF;}for(x=0;c<='9'&&c>='0'&&!_eof;c=Gc())x=x*10+(c&15),_eof|=c==EOF;x*=f;return*this;}
		template<class T>I&operator()(T*x,const int&n,const int&st=1){rep(i,st,n){operator()(x[i]);}return*this;}
	} in(stdin);
	struct O {
		char obuf[SZ],*oS=obuf,*oT=oS+SZ-1,qu[55];int f,qr;FILE*fi;
		O(FILE*f):fi(f){}
		~O(){Flush();}
		inline void Flush(){fwrite(obuf,1,oS-obuf,fi),oS=obuf;}
		inline O&operator()(char x){*oS++=x;if(oS==oT)Flush();return*this;}
		inline O&operator()(char*s){int len=strlen(s);for(f=0;f<len;++f)operator()(s[f]);return*this;}
		inline O&operator()(const char*s){return operator()((char*)s);}
		template<class T>inline O&operator()(T x){if(!x)operator()('0');if(x<0)operator()('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)operator()(qu[qr--]);return*this;}
		template<class T>O&operator()(T*x,const int&n,const char&ed=' ',const int&st=1){rep(i,st,n)operator()(x[i])(ed);return*this;}
	} out(stdout);
}
using FastIO::in;using FastIO::out;
template<class T>T Abs(const T&a){return a>0?a:-a;}
ll Pow(ll a,ll b,const ll&m){ll res=1;a%=m;while(b>0){if(b&1)res=res*a%m;a=a*a%m,b>>=1;}return res;}
ll Gcd(ll a,ll b){ll t;while(b!=0)t=a%b,a=b,b=t;return a;}
ll C(ll n,ll m){if(m>n)return 0;ll a=1;re(i,m)a*=(n-i+1),a/=i;return a;}
ll C(ll n,ll m,ll p){if(m>n)return 0;ll x=1;re(i,m){ll a=(n+i-m)%p,b=i%p;x=x*(a*Pow(b,p-2,p)%p)%p;}return x;}
// clang-format on

const int N = 1e6 + 9;

int n;
struct P {
  int x, y;
};
struct Rect {
  P a, b;
} a[N];
struct Line {
  int x, l, r, v;
};
vector<Line> vec;

struct Node {
  int l, r, lz = 0, sum = 0;
  Node *ls = 0, *rs = 0;
  Node(int l, int r) : l(l), r(r) {}

  void Up() {
    sum = 0;
    if (lz)
      sum = r - l + 1;
    else {
      if (ls) sum += ls->sum;
      if (rs) sum += rs->sum;
    }
  }

  void Add(int x) {
    lz += x;
    Up();
  }

  void Add(int L, int R, int x) {
    if (L <= l && r <= R) {
      Add(x);
      return;
    }
    int mid = (l + r) / 2;
    if (!ls) ls = new Node(l, mid);
    if (!rs) rs = new Node(mid + 1, r);
    if (L <= ls->r) ls->Add(L, R, x);
    if (rs->l <= R) rs->Add(L, R, x);
    Up();
  }
} * seg;

signed main() {
  in(n);
  re (i, n)
    in(a[i].a.x)(a[i].a.y)(a[i].b.x)(a[i].b.y);
  re (i, n) {
    int mn = min(a[i].a.y, a[i].b.y), mx = max(a[i].a.y, a[i].b.y);
    vec.push_back({a[i].a.x, mn, mx, 1}), vec.push_back({a[i].b.x, mn, mx, -1});
  }
  sort(vec.begin(), vec.end(), [](Line x, Line y) { return x.x < y.x; });
  seg = new Node(0, 1e9 + 9);
  int lst = vec[0].x;
  ll ans = 0;
  rep (i, 0, vec.size() - 1) {
    auto &x = vec[i];
    if (x.x != lst) {
      // dbg(seg->sum);
      // dbg(x.x - lst);
      ans += 1ll * seg->sum * (x.x - lst);
      lst = x.x;
    }
    seg->Add(x.l, x.r - 1, x.v);
    // cerr << x.l << ' ' << x.r - 1 << ' ' << x.v << '\n';
  }
  out(ans)('\n');
  return 0;
}
2021/9/3 20:08
加载中...