[IOI1998] Pictures
用线段树维护区间最小值和最小值个数来求一段区间里0的个数,把横的和竖的边分别拿出来,排序,然后每次查一下重复部分的长度即可
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define MAXN 5000 #define MAXL 10000 #define mid (T[k].l+T[k].r)/2 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,cnt=0,ans=0; struct sq{ int x1,y1,x2,y2; }s[MAXN+5]; struct line{ int k,l,r,x; }l[MAXL+5]; struct TREE{ int l,r,x,num,val; }T[MAXL*10]; bool cmp(line x,line y){return x.x<y.x||(x.x==y.x&&x.k<y.k);} void pushdown(int k) { int ls=k<<1,rs=(k<<1)+1; T[ls].x+=T[k].val;T[rs].x+=T[k].val; T[ls].val+=T[k].val;T[rs].val+=T[k].val; T[k].val=0; } void combine(int k) { int ls=k<<1,rs=(k<<1)+1; if(T[ls].x==T[rs].x) T[k].x=T[ls].x,T[k].num=T[ls].num+T[rs].num; else if(T[ls].x<T[rs].x) T[k].x=T[ls].x,T[k].num=T[ls].num; else T[k].x=T[rs].x,T[k].num=T[rs].num; } void renew(int k,int l,int r,int ad) { if(T[k].l==l&&T[k].r==r) {T[k].x+=ad;T[k].val+=ad;return;} if(T[k].val) pushdown(k); if(r<=mid) renew(k<<1,l,r,ad); else if(l>mid) renew((k<<1)+1,l,r,ad); else {renew(k<<1,l,mid,ad);renew((k<<1)+1,mid+1,r,ad);} combine(k); } int query(int k,int l,int r) { // cout<<"q"<<k<<" "<<l<<" "<<r<<endl; if(T[k].l==l&&T[k].r==r) { if(T[k].x>0) return T[k].r-T[k].l+1; else return T[k].r-T[k].l+1-T[k].num; } if(T[k].val) pushdown(k); if(r<=mid) return query(k<<1,l,r); else if(l>mid) return query((k<<1)+1,l,r); else return query((k<<1)+1,mid+1,r)+query(k<<1,l,mid); } void init(int k,int l,int r) { //cout<<"init"<<k<<" "<<r<<endl; T[k].l=l;T[k].r=r;T[k].val=0; if(l==r){T[k].x=0;T[k].num=1;return;} init(k<<1,l,mid);init((k<<1)+1,mid+1,r); combine(k); } int main() { n=read(); for(int i=1;i<=n;++i) { s[i].x1=read()+10001;s[i].y1=read()+10001; s[i].x2=read()+10001;s[i].y2=read()+10001; ans+=(s[i].x2+s[i].y2-s[i].y1-s[i].x1)*2; l[++cnt].k=0;l[cnt].x=s[i].x1;l[cnt].l=s[i].y1+1;l[cnt].r=s[i].y2; l[++cnt].k=1;l[cnt].x=s[i].x2;l[cnt].l=s[i].y1+1;l[cnt].r=s[i].y2; } sort(l+1,l+cnt+1,cmp);init(1,1,20005); // for(int i=1;i<=cnt;i++) // { // cout<<l[i].k<<" "<<l[i].x<<" "<<l[i].l<<" "<<l[i].r<<endl; // } for(register int i=1;i<=cnt;i++) { if(!l[i].k){ans-=query(1,l[i].l,l[i].r);renew(1,l[i].l,l[i].r,1);} else {renew(1,l[i].l,l[i].r,-1);ans-=query(1,l[i].l,l[i].r);} } cnt=0; for(register int i=1;i<=n;++i) { l[++cnt].k=0;l[cnt].x=s[i].y1;l[cnt].l=s[i].x1+1;l[cnt].r=s[i].x2; l[++cnt].k=1;l[cnt].x=s[i].y2;l[cnt].l=s[i].x1+1;l[cnt].r=s[i].x2; } sort(l+1,l+cnt+1,cmp);init(1,1,20005); // for(int i=1;i<=cnt;i++) // { // cout<<l[i].k<<" "<<l[i].x<<" "<<l[i].l<<" "<<l[i].r<<endl; // } for(register int i=1;i<=cnt;i++) { if(!l[i].k){ans-=query(1,l[i].l,l[i].r);renew(1,l[i].l,l[i].r,1);} else {renew(1,l[i].l,l[i].r,-1);ans-=query(1,l[i].l,l[i].r);} } printf("%d",ans); return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream