IOI98 Picture
IOI98 Picture 分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include <iostream> #include <vector> #include <algorithm> using namespace std; const long maxcd=16384; struct segment { long d,c1,c2,mark; }; long segcover[maxcd<<2],segcount[maxcd<<2]; //cover记录覆盖线段树某节点的线段条数; segcount统计此节点下被覆盖的长度 vector<segment> segs[2]; long border; bool operator <(const segment &a,const segment &b) { return (a.d<b.d) || ((a.d==b.d) && (a.mark>b.mark)); } void change(const long a,const long b,const long op,const long id,const long l,const long r) { if (a<=l && b>=r) segcover[id]+=op; else { if (a<(l+r)>>1 && b>(l+r)>>1) { change(a,(l+r)>>1,op,id<<1,l,(l+r)>>1); change((l+r)>>1,b,op,(id<<1)+1,(l+r)>>1,r); } else if (a<(l+r)>>1) change(a,b,op,id<<1,l,(l+r)>>1); else if (b>(l+r)>>1) change(a,b,op,(id<<1)+1,(l+r)>>1,r); } if (segcover[id]) segcount[id]=r-l; else if (r-l>1) segcount[id]=segcount[id<<1]+segcount[(id<<1)+1]; else segcount[id]=0; } int main() { long n,x1,y1,x2,y2,last=0,now=0; segment segt; cin>>n; for (;n>0;n--) { cin>>x1>>y1>>x2>>y2; x1+=maxcd; y1+=maxcd; x2+=maxcd; y2+=maxcd; segt.d=x1; segt.c1=y1; segt.c2=y2; segt.mark=1; segs[0].push_back(segt); segt.d=x2; segt.c1=y1; segt.c2=y2; segt.mark=-1; segs[0].push_back(segt); segt.d=y1; segt.c1=x1; segt.c2=x2; segt.mark=1; segs[1].push_back(segt); segt.d=y2; segt.c1=x1; segt.c2=x2; segt.mark=-1; segs[1].push_back(segt); } sort(segs[0].begin(),segs[0].end()); sort(segs[1].begin(),segs[1].end()); for (long k=0;k<=1;k++) { memset(segcover,0,sizeof(segcover)); memset(segcount,0,sizeof(segcount)); for (unsigned long i=0;i<segs[k].size();i++) { change(segs[k][i].c1,segs[k][i].c2,segs[k][i].mark,1,0,maxcd<<1); last=now; now=segcount[1]; border+=abs(now-last); } } cout<<border<<endl; return 0; } |
