zoukankan      html  css  js  c++  java
  • 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 */
    洛谷的数据好水

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

  • 相关阅读:
    python3.4 + pycharm 环境安装 + pycharm使用
    ddt源码修改:HtmlTestRunner报告依据接口名显示用例名字
    re模块
    LeetCode Weekly Contest 12
    求解强连通分量
    几道题-找规律-记录并查找
    欧几里德算法
    树上二分
    几道题-博弈
    随便写一些东西-缩边
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/8629874.html
Copyright © 2011-2022 走看看