标签:node typedef 次数 int 的区别 class line clu 线段树
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn=2e5+10; //因为一个矩形有两边所以数据范围要乘2 int y[maxn]; struct L { int x; //竖边的x坐标 int y1,y2; //竖边的y坐标,y1较小 int state; //是左边还是右边 bool operator<(const L &b)const //排序时使用x坐标排序 { return x<b.x; } } line[maxn]; struct node //线段树 { int l,r; //结点区间左右 int cover; //被覆盖次数 ll len; //区间真实长度 } sgt[maxn<<3]; //注意这个大小 inline void pushup(int k) //与普通线段树的区别 { if (sgt[k].cover) { sgt[k].len=sgt[k].r-sgt[k].l; } else { sgt[k].len=sgt[k<<1].len+sgt[k<<1|1].len; } } void build (int rt,int l,int r) { sgt[rt].l=y[l]; sgt[rt].r=y[r]; //与普通线段树的区别 if (r-l<=1) return; //与普通线段树的区别 int mid=(r+l)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid,r); } void update(int rt,int x,int y,int z) { int l=sgt[rt].l,r=sgt[rt].r; if (x<=l&&r<=y) { sgt[rt].cover+=z; pushup(rt); return; } if (x<sgt[rt<<1].r) update(rt<<1,x,y,z); //与普通线段树的区别 if (y>sgt[rt<<1|1].l) update(rt<<1|1,x,y,z); //与普通线段树的区别 pushup(rt); } int main() { int n; scanf("%d",&n); for (int i=1,x1,x2,y1,y2; i<=n; i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); y[i]=y1; y[i+n]=y2; line[i]=L{x1,y1,y2,1}; line[i+n]=L{x2,y1,y2,-1}; } line[0].x=0; sort(y+1,y+1+n*2); sort(line+1,line+n*2+1); build (1,1,n<<1); ull ans=0; //爆int的毒瘤数据只好用ull处理 for (int i=1; i<=n<<1; i++) { ans+=1ull*sgt[1].len*(line[i].x-line[i-1].x); update(1,line[i].y1,line[i].y2,line[i].state); } printf("%llu\n",ans); return 0; }
标签:node typedef 次数 int 的区别 class line clu 线段树
原文地址:https://www.cnblogs.com/Accpted/p/11367422.html