P1856 矩形周长
哇!这小破题坑了我好久。
扫描线+线段树
这题数据范围小,没离散化。真要离散化我还搞不好呢。
具体的看这个博客吧。
主要是这个坑爹的c,len把我搞了,其他的还好。
代码:
1 #include <cstdio> 2 #include <queue> 3 #include <cmath> 4 using namespace std; 5 struct Node 6 { 7 int len,s; 8 } node[400010]; 9 struct Edge 10 { 11 int L,R,high,flag; 12 bool operator < (const Edge &a) const 13 { 14 if(this->high!=a.high)return this->high>a.high; 15 return this->flag<a.flag; 16 } 17 }; 18 priority_queue<Edge>x; 19 priority_queue<Edge>y; 20 void build(int l,int r,int o) 21 { 22 node[o].len=0; 23 node[o].s=0; 24 if(l==r) return; 25 int mid=(l+r)>>1; 26 build(l,mid,o<<1); 27 build(mid+1,r,o<<1|1); 28 return; 29 } 30 void up(int l,int r,int o) 31 { 32 if(node[o].s) node[o].len=r-l+1; 33 else if(l==r) node[o].len=0; 34 else node[o].len=node[o<<1].len+node[o<<1|1].len; 35 return; 36 } 37 void add(int L,int R,int v,int l,int r,int o) 38 { 39 //printf("add:%d %d %d %d %d %d\n",L,R,v,l,r,o); 40 if(L<=l && r<=R) 41 { 42 node[o].s+=v; 43 up(l,r,o); 44 return;///这里的return一开始忘了打,死循环。 45 } 46 if(R<l || r<L) return; 47 int mid=(l+r)>>1; 48 if(L<=mid) add(L,R,v,l,mid,o<<1); 49 if(mid<R) add(L,R,v,mid+1,r,o<<1|1); 50 up(l,r,o); 51 return; 52 } 53 void adde(int x1,int y1,int x2,int yyy) 54 { 55 Edge xup,xlow,yup,ylow; 56 xup.L=xlow.L=ylow.high=x1; 57 xup.R=xlow.R=yup.high=x2; 58 yup.L=ylow.L=xlow.high=y1; 59 yup.R=ylow.R=xup.high=yyy; 60 xlow.flag=ylow.flag=1; 61 xup.flag=yup.flag=-1; 62 //printf("adde:%d %d %d %d\n",xup.L,xup.R,xup.high,xup.flag); 63 //printf("adde:%d %d %d %d\n",xlow.L,xlow.R,xlow.high,xlow.flag); 64 x.push(xup); 65 x.push(xlow); 66 y.push(yup); 67 y.push(ylow); 68 return; 69 } 70 int main() 71 { 72 int N = 20010; 73 build(1,N,1); 74 int n,x1,x2,y1,yyy; 75 scanf("%d",&n); 76 for(int i=1; i<=n; i++) 77 { 78 scanf("%d%d%d%d",&x1,&y1,&x2,&yyy);///这里 的变量名传错了,0分 79 adde(x1+10001,y1+10001,x2+10001,yyy+10001); 80 } 81 Edge e;int len=0; 82 long long int ans=0; 83 while(!x.empty()) 84 { 85 //printf("x\n"); 86 e=x.top(); 87 x.pop(); 88 //printf("edge:%d %d %d %d\n",e.L,e.R,e.high,e.flag); 89 add(e.L,e.R-1,e.flag,1,N,1); 90 ans+=abs(node[1].len-len); 91 len=node[1].len; 92 //printf("ans=%d\n",ans); 93 } 94 build(1,N,1);len=0; 95 while(!y.empty()) 96 { 97 //printf("y\n"); 98 e=y.top(); 99 //printf("edge:%d %d %d %d\n",e.L,e.R,e.high,e.flag); 100 y.pop(); 101 add(e.L,e.R-1,e.flag,1,N,1); 102 ans+=abs(node[1].len-len); 103 len=node[1].len; 104 //printf("ans=%d\n",ans); 105 } 106 printf("%lld",ans); 107 return 0; 108 } 109 /** 110 4 111 1 1 2 2 112 3 1 5 3 113 4 0 6 2 114 5 -1 7 1 115 116 20 117 */
还有更高级的方法我没搞了,晦涩难懂......