zoukankan      html  css  js  c++  java
  • hdu 4419 线段树 扫描线 离散化 矩形面积

      1 //离散化 + 扫描线 + 线段树
      2 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层。len[i]起传递儿子与父亲的关系,而num[i]不起传递作用,只是单纯的表示被覆盖的区间。
      3 //然后就是pushUp函数,必须在update到底层后即更新num[]和len,然后把len传上去。
      4 //离散化后由于求的是面积,所以我是把每条长度为1的线段当做一个点, 即把左端点表示此段长度。而不是把点当成点。
      5 #include <iostream>
      6 #include <cstdio>
      7 #include <algorithm>
      8 #include <cstring>
      9 #include <cmath>
     10 
     11 using namespace std;
     12 #define lson l, m, rt<<1
     13 #define rson m + 1, r, rt<<1|1
     14 typedef long long ll;
     15 const int maxn = 2e4 + 5;
     16 
     17 struct Seg{
     18     char c;
     19     int y, s, t, tag;
     20 }ss[maxn];
     21 bool cmp(Seg a, Seg b){
     22     return a.y < b.y;
     23 }
     24 int san[maxn], tot;
     25 int num[maxn << 2][5],len[maxn << 2][8];
     26 ll ans[8];
     27 void pushUp(int l, int r, int rt){
     28     int state = (num[rt][1] > 0 ? 1 : 0) | (num[rt][2] > 0 ? 2 : 0) | (num[rt][4] > 0 ? 4 : 0);
     29     memset(len[rt], 0, sizeof(len[rt]));
     30     if (state){
     31         len[rt][state] = san[r] - san[l - 1];
     32         for (int i = 1; i < 8; ++i){
     33             if (state != (state|i)){
     34                 int tmp = len[rt<<1][i] + len[rt<<1|1][i];
     35                 len[rt][state|i] += tmp;
     36                 len[rt][state] -= tmp;
     37             }
     38         }
     39     }
     40     else if (l != r){
     41         for (int i = 1; i < 8; ++i) len[rt][i] = len[rt<<1][i] + len[rt<<1|1][i];
     42     }
     43 }
     44 int getC(char c){
     45     if (c == 'R') return 1;
     46     if (c == 'G') return 2;
     47     return 4;
     48 }
     49 void update(int L, int R, char c, int tag, int l, int r, int rt){
     50     if (L <= l && R >= r){
     51         int cc = getC(c);
     52         num[rt][cc] += tag;
     53         //注意
     54         pushUp(l, r, rt);
     55         return ;
     56     }
     57     int m = (l + r) >> 1;
     58     if (L <= m) update(L, R, c, tag, lson);
     59     if (R > m) update(L, R, c, tag, rson);
     60     pushUp(l, r, rt);
     61 }
     62 int T,  n;
     63 int main(){
     64     int tcas = 0;
     65     int x1, x2, y1, y2;
     66     char s[3];
     67     scanf("%d", &T);
     68     while (T--){
     69         scanf("%d", &n);
     70         tot = 0;
     71         for (int i = 1; i <= n; ++i){
     72             scanf("%s%d%d%d%d", s,&x1, &y1, &x2, &y2); 
     73             ss[i].c = s[0]; ss[i].y = y1; ss[i].s = x1; ss[i].t = x2, ss[i].tag= 1;
     74             ss[i + n].c = s[0]; ss[i + n].y = y2; ss[i + n].s = x1; ss[i + n].t = x2, ss[i + n].tag = -1;
     75             san[tot++] = x1 ; san[tot++] = x2;
     76         }
     77         n = n * 2;
     78 
     79         sort(san, san + tot);
     80         tot = unique(san, san + tot) - san;
     81         sort(ss + 1, ss + n + 1, cmp);
     82         ss[0].y = ss[1].y;
     83         
     84         memset(num, 0, sizeof(num));
     85         memset(len, 0, sizeof(len));
     86         memset(ans, 0, sizeof(ans));
     87         for (int i = 1; i <= n; ++i){
     88             int l = lower_bound(san, san + tot, ss[i].s) - san + 1;
     89             int r = lower_bound(san, san + tot, ss[i].t) - san;
     90             /*cout << " l = " << l << " r = " << r ;
     91             cout << " tag = " << ss[i].tag << " c = "<< ss[i].c << endl;
     92             for (int j = 1; j < 8; ++j) cout << len[1][j] << " ";
     93             cout << endl;
     94             cout << endl;
     95             */
     96             if (ss[i].y != ss[i - 1].y){
     97                 for (int j = 1; j < 8; ++j){
     98                     ans[j] += (ll)(ss[i].y - ss[i - 1].y) * (ll)len[1][j];
     99                 }
    100             }
    101             update(l, r, ss[i].c, ss[i].tag, 1, tot - 1, 1);
    102         }
    103         printf("Case %d:
    ", ++tcas);
    104         swap(ans[3], ans[4]);
    105         for (int i = 1; i < 8; ++i)
    106             printf("%lld
    ", ans[i]);
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    linux centos&Ubuntu&RedHat更换软件源
    linux及windows安装maven
    No converter found for return value of type: class com.alibaba.fastjson.JSON解决办法
    linux sudo命令失败 提示sudo:/usr/bin/sudo 必须属于用户 ID 0(的用户)并且设置 setuid 位
    Linux常用命令
    Linux安装Java+Eclipse或IDEA
    Python基础编程:字符编码、数据类型、列表
    linux系统挂载u盘拷贝文件
    linux(服务器)如何确认网卡(网口)对应的配置文件
    Python第三方库requests的编码问题
  • 原文地址:https://www.cnblogs.com/Missa/p/3415557.html
Copyright © 2011-2022 走看看