• 【HDU4419 Colourful Rectangle】 线段树面积并


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419

    题目大意:给你n个矩形,每个矩形都有一种颜色,矩形覆盖会出现另外一种颜色,问你所有矩形中不同的颜色各出现的面积。

    解题思路:开始一直只用一个标记,1,2,4,处理来处理去发现一直搞不来。最后用两个标记,一个存+1,-1,和普通面积并类似,另外开一个三位的标记数组,0位表示'R',1位表示‘G’,2位表示‘B’,sum数组要开8个状态(和8颗线段树思想类似),每次处理到当前节点时,该节点所有sum值清0(叶子节点的sum[u][0]表示的就是区间长度,要进行预先建树),根据自己当前的状态再由孩子传递数值上来进行更新操作。这题很巧妙的用到了或运算,表示我开始没想到,发散性思维 O.O。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 #define lz 2*u,l,mid
      8 #define rz 2*u+1,mid+1,r
      9 typedef long long lld;
     10 const int maxn=22222;
     11 lld sum[4*maxn][10];
     12 int flag[4*maxn][3];
     13 int X[maxn];
     14 lld ans[8];
     15 
     16 struct Node
     17 {
     18     int lx, rx, y;
     19     int c, s;
     20     Node() {};
     21     Node(int lx_, int rx_, int y_, int c_, int s_)
     22     {
     23         lx=lx_, rx=rx_, y=y_, c=c_, s=s_;
     24     }
     25     bool operator <(const Node &S) const
     26     {
     27         if(y==S.y) return s>S.s;
     28         else return y<S.y;
     29     }
     30 } line[maxn];
     31 
     32 int find(int tmp, int n)
     33 {
     34     int l=1, r=n, mid;
     35     while(l<=r)
     36     {
     37         mid=(l+r)>>1;
     38         if(X[mid]==tmp) return mid;
     39         else if(X[mid]<tmp) l=mid+1;
     40         else r=mid-1;
     41     }
     42 }
     43 
     44 void push_up(int u, int l, int r)
     45 {
     46     int state=0;
     47     for(int i=0; i<=2; i++) if(flag[u][i]) state|=(1<<i);
     48     memset(sum[u],0,sizeof(sum[u]));
     49     if(l==r) sum[u][state]=X[r+1]-X[l];
     50     else
     51     {
     52         for(int i=0; i<8; i++)
     53             sum[u][state|i]+=sum[2*u][i]+sum[2*u+1][i];
     54     }
     55 }
     56 
     57 void build(int u, int l, int r)
     58 {
     59     memset(sum[u],0,sizeof(sum[u]));
     60     memset(flag[u],0,sizeof(flag[u]));
     61     if(l==r)
     62     {
     63         sum[u][0]=X[r+1]-X[l];
     64         return ;
     65     }
     66     int mid=(l+r)>>1;
     67     build(lz);
     68     build(rz);
     69     sum[u][0]=sum[2*u][0]+sum[2*u+1][0];
     70 }
     71 
     72 void Update(int u, int l, int r, int tl, int tr, int s, int c)
     73 {
     74     if(tl>tr) return ;
     75     if(tl<=l&&r<=tr)
     76     {
     77         flag[u][s]+=c;
     78         push_up(u,l,r);
     79         return ;
     80     }
     81     int mid=(l+r)>>1;
     82     if(tr<=mid) Update(lz,tl,tr,s,c);
     83     else if(tl>mid) Update(rz,tl,tr,s,c);
     84     else
     85     {
     86         Update(lz,tl,mid,s,c);
     87         Update(rz,mid+1,tr,s,c);
     88     }
     89     push_up(u,l,r);
     90 }
     91 
     92 int main()
     93 {
     94     int n, T, tcase=0;
     95     cin >> T;
     96     while(T--)
     97     {
     98         cin >> n;
     99         int num=0;
    100         memset(flag,0,sizeof(flag));
    101         memset(sum,0,sizeof(sum));
    102         memset(ans,0,sizeof(ans));
    103         for(int i=0; i<n; i++)
    104         {
    105             int x1,x2,y1,y2, s;
    106             char ch[2];
    107             scanf("%s%d%d%d%d",ch,&x1,&y1,&x2,&y2);
    108             if(ch[0]=='R') s=0;
    109             else if(ch[0]=='G') s=1;
    110             else s=2;
    111             line[++num]=Node(x1,x2,y1,s,1);
    112             X[num]=x1;
    113             line[++num]=Node(x1,x2,y2,s,-1);
    114             X[num]=x2;
    115         }
    116         sort(X+1,X+num+1);
    117         sort(line+1,line+num+1);
    118         int k=1;
    119         for(int i=2; i<=num; i++)
    120             if(X[i]!=X[i+1]) X[++k]=X[i];
    121         build(1,1,k);
    122         for(int i=1; i<num; i++)
    123         {
    124             int l=find(line[i].lx,k);
    125             int r=find(line[i].rx,k)-1;
    126             Update(1,1,k,l,r,line[i].c,line[i].s);
    127             for(int j=1; j<=7; j++)
    128                 ans[j]+=sum[1][j]*(line[i+1].y-line[i].y);
    129         }
    130         printf("Case %d:
    ",++tcase);
    131         swap(ans[3],ans[4]);
    132         for(int i=1; i<=7; i++)  cout << ans[i] <<endl;
    133     }
    134     return 0;
    135 }
    View Code
  • 相关阅读:
    Asp.net mvc 使用Ajax调用Action 返回数据。
    浅析Asp.net MVC 中Ajax的使用
    Asp.net MVC2中使用Ajax的三种方式
    Ajaxa请求:参数、传递的数据、返回的数据
    ASP.NET MVC 模块与组件——发送邮件
    MVC中根据后台绝对路径读取图片并显示在IMG中
    MVC、一般处理程序hanlder 输出图片文件
    邮箱验证功能原理 语法 属性
    C# 注册邮箱验证的实现代码
    注册页实现激活邮箱验证(asp.net c#) 详细实现
  • 原文地址:https://www.cnblogs.com/kane0526/p/3219163.html
Copyright © 2020-2023  润新知