题解:http://www.notonlysuccess.com/index.php/segment-tree-complete/
题意:求矩形周长
分析:与面积不同的地方是还要记录竖的边有几个(numseg记录)也就是[记录线段树被覆盖的区间有多少个],并且当边界重合的时候需要合并(用lbd和rbd表示边界来辅助)
线段树操作:update:区间增减 query:直接取根节点的值
// File Name: 1177.cpp // Author: Zlbing // Created Time: 2013/7/20 19:53:20 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,r,n) for(int i=r;i<=n;i++) #define RREP(i,n,r) for(int i=n;i>=r;i--) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int MAXN=1e4+100; struct seg{ int x1,x2,y; int flag; bool operator <(const seg& rsh)const { if(y==rsh.y)return flag>rsh.flag; else return y<rsh.y; } }G[MAXN]; int hash[MAXN]; int col[MAXN<<2]; int sum[MAXN<<2]; bool lbd[MAXN<<2],rbd[MAXN<<2]; int numseg[MAXN<<2]; void pushup(int rt,int l,int r) { if(col[rt]){ lbd[rt]=1,rbd[rt]=1; numseg[rt]=2; sum[rt]=hash[r+1]-hash[l]; } else if(l==r){ sum[rt]=lbd[rt]=rbd[rt]=numseg[rt]=0; } else{ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; lbd[rt]=lbd[rt<<1]; rbd[rt]=rbd[rt<<1|1]; numseg[rt]=numseg[rt<<1]+numseg[rt<<1|1]; if(lbd[rt<<1|1]&&rbd[rt<<1])numseg[rt]-=2;//两条线重合 } } void update(int L,int R,int flag,int l,int r,int rt) { if(L<=l&&R>=r) { col[rt]+=flag; pushup(rt,l,r); return; } int m=(l+r)>>1; if(L<=m)update(L,R,flag,lson); if(R>m)update(L,R,flag,rson); pushup(rt,l,r); } int main() { int n; while(~scanf("%d",&n)) { int a,b,c,d; int xlen=0; REP(i,1,n) { scanf("%d%d%d%d",&a,&b,&c,&d); G[xlen].x1=a,G[xlen].x2=c,G[xlen].y=b,G[xlen].flag=1; hash[xlen]=a; xlen++; G[xlen].x1=a,G[xlen].x2=c,G[xlen].y=d,G[xlen].flag=-1; hash[xlen]=c; xlen++; } sort(G,G+xlen); sort(hash,hash+xlen); int len=unique(hash,hash+xlen)-hash; int ans=0; int last=0; for(int i=0;i<xlen;i++) { int x1=lower_bound(hash,hash+len,G[i].x1)-hash; int x2=lower_bound(hash,hash+len,G[i].x2)-hash-1; update(x1,x2,G[i].flag,0,len-1,1); ans+=numseg[1]*(G[i+1].y-G[i].y); ans+=abs(sum[1]-last); last=sum[1]; } printf("%d ",ans); } return 0; }