法一:二维线段树
#include<iostream>
#include<cstdio>
#include<cstdarg>
#include<stdlib.h>
#include<cstring>
#include<cmath>
using namespace std;
const int N=10005;
struct Node
{
int xMin;
int xMax;
int yMin;
int yMax;
int area;
bool cover;
}aNode[3*N];
void build(int xMin,int xMax,int yMin,int yMax,int n)
{
if((xMax-xMin==1)&&(yMax-yMin==1))
{
aNode[n].xMin=xMin;
aNode[n].xMax=xMax;
aNode[n].yMin=yMin;
aNode[n].yMax=yMax;
aNode[n].area=1;
aNode[n].cover=0;
}
else if((xMax==xMin)||(yMax==yMin))
{
aNode[n].xMin=xMin;
aNode[n].xMax=xMax;
aNode[n].yMin=yMin;
aNode[n].yMax=yMax;
aNode[n].area=0;
aNode[n].cover=1;
}
else
{
int xMid=(xMax+xMin)>>1;
int yMid=(yMax+yMin)>>1;
aNode[n].xMin=xMin;
aNode[n].xMax=xMax;
aNode[n].yMin=yMin;
aNode[n].yMax=yMax;
build(xMin,xMid,yMin,yMid,4*n-2);
build(xMin,xMid,yMid,yMax,4*n-1);
build(xMid,xMax,yMid,yMax,4*n);
build(xMid,xMax,yMin,yMid,4*n+1);
aNode[n].area=aNode[4*n-2].area+aNode[4*n-1].area+aNode[4*n].area+aNode[4*n+1].area;
aNode[n].cover=0;
}
}
void insert(int xMin,int xMax,int yMin,int yMax,int n)
{
int xMid=(aNode[n].xMin+aNode[n].xMax)>>1;
int yMid=(aNode[n].yMin+aNode[n].yMax)>>1;
if((xMin==aNode[n].xMin)&&(xMax==aNode[n].xMax)&&(yMin==aNode[n].yMin)&&(yMax==aNode[n].yMax))
{
aNode[n].cover=1;
}
else
{
if(aNode[n].cover==0)
{
if((xMax<=xMid))
{
if(yMax<=yMid)
{
insert(xMin,xMax,yMin,yMax,4*n-2);
}
else if(yMin>=yMid)
insert(xMin,xMax,yMin,yMax,4*n-1);
else
{
insert(xMin,xMax,yMin,yMid,4*n-2);
insert(xMin,xMax,yMid,yMax,4*n-1);
}
}
else if(xMin>=xMid)
{
if(yMax<=yMid)
insert(xMin,xMax,yMin,yMax,4*n+1);
else if(yMin>=yMid)
insert(xMin,xMax,yMin,yMax,4*n);
else
{
insert(xMin,xMax,yMid,yMax,4*n);
insert(xMin,xMax,yMin,yMid,4*n+1);
}
}
else
{
if(yMin>=yMid)
{
insert(xMin,xMid,yMin,yMax,4*n-1);
insert(xMid,xMax,yMin,yMax,4*n);
}
else if(yMax<=yMid)
{
insert(xMin,xMid,yMin,yMax,4*n-2);
insert(xMid,xMax,yMin,yMax,4*n+1);
}
else
{
insert(xMin,xMid,yMin,yMid,4*n-2);
insert(xMin,xMid,yMid,yMax,4*n-1);
insert(xMid,xMax,yMid,yMax,4*n);
insert(xMid,xMax,yMin,yMid,4*n+1);
}
}
aNode[n].cover=((aNode[4*n-2].cover)&(aNode[4*n-1].cover)&(aNode[4*n].cover)&(aNode[4*n+1].cover));
}
}
}
int query(int n)
{
if(aNode[n].cover==1) return aNode[n].area;
else if((aNode[n].xMax-aNode[n].xMin==1)&&(aNode[n].yMax-aNode[n].yMin==1))
return 0;
else
{
return (query(4*n-2)+query(4*n-1)+query(4*n)+query(4*n+1));
}
}
int main()
{
int xMin,xMax,yMin,yMax;
build(0,100,0,100,1);
while(scanf("%d %d %d %d",&xMin,&yMin,&xMax,&yMax)==4)
{
if((xMin==-1)&&(yMin==-1)&&(xMax==-1)&&(yMax==-1))
{
int ans=query(1);
printf("%d\n",ans);
build(0,100,0,100,1);
continue;
}
else if((xMin==-2)&&(yMin==-2)&&(xMax==-2)&&(yMax==-2))
{
int ans=query(1);
printf("%d\n",ans);
build(0,100,0,100,1);
break;
}
else
{ int x1,x2,y1,y2;
x1=min(xMin,xMax);
x2=max(xMin,xMax);
y1=min(yMin,yMax);
y2=max(yMin,yMax);
insert(x1,x2,y1,y2,1);
}
}
//system("pause");
return 0;
}
法二:离散化+一维线段树
/*
ID:billat11
LANG:C
TASK:namenum
*/
#include<iostream>
#include<cstdio>
#include<cstdarg>
#include<stdlib.h>
#include<cstring>
#include<cmath>
using namespace std;
const int N=100;
typedef struct treeNode
{
int l;
int r;
int f;
}tnode;
struct segtree
{
tnode tn[3*N];
};
struct segtree st[N+5];
void build(struct segtree &s,int l,int r,int n)
{
int mid=(l+r)>>1;
if(r-l==1)
{
s.tn[n].l=l;
s.tn[n].r=r;
s.tn[n].f=0;
}
else
{
s.tn[n].l=l;
s.tn[n].r=r;
s.tn[n].f=0;
build(s,l,mid,2*n);
build(s,mid,r,2*n+1);
}
}
void print(struct segtree s,int n)
{
printf("node %d left:%d right:%d flag:%d\n",n,s.tn[n].l,s.tn[n].r,s.tn[n].f);
if(s.tn[n].r-s.tn[n].l==1) return;
else
{
print(s,2*n);
print(s,2*n+1);
}
}
void insert(struct segtree &s,int l,int r,int n)
{
int mid=(s.tn[n].l+s.tn[n].r)>>1;
if((s.tn[n].f==1)||(s.tn[n].l==l&&s.tn[n].r==r))
{
s.tn[n].f=1;
return;
}
else
{
if(r<=mid)
{
insert(s,l,r,2*n);
}
else if(l>=mid)
{
insert(s,l,r,2*n+1);
}
else
{
insert(s,l,mid,2*n);
insert(s,mid,r,2*n+1);
}
s.tn[n].f=(s.tn[2*n].f)&(s.tn[2*n+1].f);
}
}
int query(struct segtree s,int n)
{
if(s.tn[n].f==1) return (s.tn[n].r-s.tn[n].l);
else if(s.tn[n].r-s.tn[n].l>1)
{
return (query(s,2*n)+query(s,2*n+1));
}
return 0;
}
int main()
{
int xMin,xMax,yMin,yMax;
for(int i=0;i<=N+2;i++)
build(st[i],0,100,1);
while(scanf("%d %d %d %d",&xMin,&yMin,&xMax,&yMax)==4)
{
if((xMin==-1)&&(yMin==-1)&&(xMax==-1)&&(yMax==-1))
{
int ans=0;
for(int i=0;i<100;i++)
ans+=query(st[i],1);
printf("%d\n",ans);
for(int i=0;i<=N+2;i++)
build(st[i],0,100,1);
continue;
}
else if((xMin==-2)&&(yMin==-2)&&(xMax==-2)&&(yMax==-2))
{
int ans=0;
for(int i=0;i<100;i++)
ans+=query(st[i],1);
printf("%d\n",ans);
for(int i=0;i<=N+2;i++)
build(st[i],0,100,1);
break;
}
else
{ int x1,x2,y1,y2;
x1=min(xMin,xMax);
x2=max(xMin,xMax);
y1=min(yMin,yMax);
y2=max(yMin,yMax);
for(int i=x1;i<x2;i++)
insert(st[i],y1,y2,1);
}
}
//system("pause");
return 0;
}