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
",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
",xup.L,xup.R,xup.high,xup.flag);
 63     //printf("adde:%d %d %d %d
",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
");
 86         e=x.top();
 87         x.pop();
 88         //printf("edge:%d %d %d %d
",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
",ans);
 93     }
 94     build(1,N,1);len=0;
 95     while(!y.empty())
 96     {
 97         //printf("y
");
 98         e=y.top();
 99         //printf("edge:%d %d %d %d
",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
",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 */
洛谷的数据好水

还有更高级的方法我没搞了,晦涩难懂......

原文地址:https://www.cnblogs.com/huyufeifei/p/8629874.html