• sgu316Kalevich Strikes Back(线段树+扫描线)


    做法:总体想法是求出一个矩形的面积以及它所包含的矩形,然后用自己的面积减掉所包含的。主要问题是怎样求解它所包含的矩形。

    因为是没有相交点的,可以利用扫描线的方法去做,类似染色,当前段如果是x色,也就是第x个矩形,那么再把他染成y颜色时,说明x包含y,而当扫到y的上边时,这一段又恢复到x色。标记一下被包含的矩形,记录所包含的矩形。

    因为会有恢复染色操作,up需要时时更新,左儿子和右儿子一样颜色时就可以合并为一段。

      1 ;
      2 }
      3 void down(int w)
      4 {
      5     if(s[w]!=-1)
      6     {
      7         s[w<<1] = s[w<<1|1] = s[w];
      8         s[w] = -1;
      9     }
     10 }
     11 void build(int l,int r,int w)
     12 {
     13     s[w] = 0;
     14     if(l==r)
     15     {
     16         return ;
     17     }
     18     int m = (l+r)>>1;
     19     build(l,m,w<<1);
     20     build(m+1,r,w<<1|1);
     21     up(w);
     22 }
     23 int update(int a,int b,int d,int l,int r,int w)
     24 {
     25     if(a<=l&&b>=r)
     26     {
     27         int k = s[w];
     28        // cout<<l<<" "<<r<<" "<<s[w]<<endl;
     29         s[w] = d;
     30         return k;
     31     }
     32     down(w);
     33     int m  = (l+r)>>1;
     34     int k = 0;
     35     if(a<=m)
     36     k = update(a,b,d,l,m,w<<1);
     37     if(b>m)
     38     k = update(a,b,d,m+1,r,w<<1|1);
     39     up(w);
     40     return k;
     41 }
     42 int main()
     43 {
     44     int n,w,h,i,j;
     45     scanf("%d%d%d",&n,&w,&h);
     46     int g = 0;
     47     for(i = 1;i <= n; i++)
     48     {
     49         int x1,x2,y1,y2;
     50         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
     51         p[++g] = node(x1,x2,min(y1,y2),i);
     52         a[g] = x1;
     53         p[++g] = node(x1,x2,max(y1,y2),-i);
     54         a[g] = x2;
     55         sum[i] = (LL)abs(x1-x2)*abs(y1-y2);
     56     }
     57     sort(p+1,p+g+1);
     58     sort(a+1,a+g+1);
     59     int o = 0;
     60     f[a[1]] = ++o;
     61     for(i = 2; i <= g;i++)
     62     {
     63         if(a[i]!=a[i-1])
     64         {
     65             f[a[i]] = ++o;
     66             val[o] =a[i];
     67         }
     68     }
     69     build(1,o,1);
     70     for(i = 1; i <= g;i++)
     71     {
     72         int l = min(f[p[i].x1],f[p[i].x2]);
     73         int r = max(f[p[i].x2],f[p[i].x1]);
     74         //cout<<l<<" "<<r<<endl;
     75         if(l<=r)
     76         {
     77             if(p[i].d>0)
     78             {
     79                 int k = update(l,r,p[i].d,1,o,1);
     80                 ed[k].push_back(p[i].d);
     81                 pre[p[i].d] = k;
     82                 //cout<<k<<" "<<p[i].d<<endl;
     83             }
     84             else
     85             {
     86                 update(l,r,pre[-p[i].d],1,o,1);
     87             }
     88             //fresh(l,r,1,o,1);
     89         }
     90     }
     91     sum[0] =(LL)w*h;
     92     for(i = 0 ;i <= n; i++)
     93     ans[i] = sum[i];
     94     for(i = 0; i <= n; i++)
     95     {
     96         for(j = 0 ;j < ed[i].size() ; j++)
     97         {
     98             int v = ed[i][j];
     99             ans[i]-=sum[v];
    100         }
    101     }
    102     sort(ans,ans+n+1);
    103     for(i = 0 ;i < n; i++)
    104     printf("%I64d ",ans[i]);
    105     printf("%I64d
    ",ans[n]);
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    winform登录成功后打开主窗体的合理写法
    C#将字符串转换为整型的三种方法的总结
    win7下安装Oracle11g
    无法将文件“.exe”复制到“.exe”。文件“.exe”正由另一进程使用,因此该进程无法访问该文件
    GDI+
    “System.Data.SqlClient.SqlConnection”的类型初始值设定项引发异常
    winform中为ComboBox控件添加“请选择”或“全部”选项
    IE8不能上传、插入图片的解决办法!
    asp.net mvc实现上传文件
    winform关闭窗体时确认框提示两次
  • 原文地址:https://www.cnblogs.com/shangyu/p/3774146.html
Copyright © 2020-2023  润新知