• Cubes-Codeforces-180E


    Cubes:

    我们先将每个正方形的光路投影找出来(在y轴上的截距所构成的区间)

    然后,我们再考虑按照光线射到的先后顺序加入每个方格。

    再用线段树统计这个投影区间内的最小高度的光线。这样我们就能够算出每个点被照亮的高度。

    复杂度O(n2logn+).

    注意:

    在计算区间的时候选择前闭后开区间,这是因为我们要满足两个条件,

    1.只通过一个点的光线不算照亮

    2.假设先后修改(2,3),(1,2),(4,5)那么现在的(2,3)区间不能是(1,2)或(4,5)中间的一个.

    代码很丑,凑合着看吧.(数据似乎没有和坐标轴平行的光,我就没管了.....)

      1 #include<cstdlib>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<map>
      7 using namespace std;
      8 const int maxn = 510, maxs = maxn * maxn * 5,inf = 0x3f3f3f3f;
      9 const int dx[] = {0,0,0,1,1},
     10        dy[] = {0,0,1,0,1};
     11 int ct;
     12 struct SEG{
     13     int sg[maxs * 3],tag[maxs * 3];
     14     void down(int x){
     15         if(tag[x]){
     16             sg[x << 1] = max(sg[x << 1], tag[x]);
     17             sg[x << 1|1] = max(sg[x << 1|1], tag[x]);
     18             tag[x << 1] = max(tag[x << 1], tag[x]);
     19             tag[x <<1|1] = max(tag[x << 1|1], tag[x]);
     20             tag[x] = 0;
     21         }
     22     }
     23     int qer(int x,int l,int r,int nl,int nr){
     24         down(x);
     25         if(l == nl && nr == r) return sg[x];
     26         int mid = (nl + nr) >> 1;
     27         if(r <= mid) return qer(x << 1, l, r, nl, mid);
     28         else if(l > mid) return qer(x << 1|1, l, r, mid + 1, nr);
     29         else{
     30             int t1 = qer(x << 1, l, mid, nl, mid);
     31             int t2 = qer(x << 1|1, mid + 1, r, mid+1, nr);
     32             return min(t1,t2);
     33         }
     34     }
     35     void mod(int x,int l,int r,int nl,int nr,int val){
     36         down(x);
     37         if(l == nl && nr == r){
     38             sg[x] = max(sg[x],val), tag[x] = max(tag[x],val);
     39             return;
     40         }
     41         int mid = (nl + nr) >> 1;
     42         if(r <= mid){
     43             mod(x << 1, l, r, nl, mid, val);
     44         }
     45         else if(l > mid){
     46             mod(x << 1|1, l, r, mid + 1, nr, val);            
     47         }
     48         else{
     49             mod(x << 1, l, mid, nl, mid, val);
     50             mod(x << 1|1, mid + 1, r, mid + 1, nr, val);    
     51         }
     52         sg[x] = min(sg[x << 1], sg[x << 1|1]);
     53     }
     54     
     55 }seg;
     56 int n,vx,vy;
     57 int tot;
     58 struct grid{
     59     int x,y;
     60     long long height;
     61 }g[maxn * maxn + 100];
     62 int cmp(grid x, grid y){
     63     if(x.x != y.x) return x.x > y.x;
     64     return x.y > y.y;
     65 }
     66 void trans(){
     67     if(vx > 0){
     68         vx = -vx;
     69         for(int i = 1; i <= tot; ++i) g[i].x = n - g[i].x - 1;
     70     }
     71     if(vy > 0){
     72         vy = -vy;
     73         for(int i = 1; i <= tot; ++i) g[i].y = n - g[i].y - 1;
     74     }
     75     if(vx == 0 && vy != 0){
     76         swap(vx,vy);
     77         for(int i = 1; i <= tot; ++i){
     78             swap(g[i].x, g[i].y);
     79             g[i].y = n - g[i].y - 1;
     80         }
     81     }
     82 }
     83 struct I{
     84     long long it;
     85     int rank;
     86 }data[maxn][maxn];
     87 map<long long, int>v;
     88 map<long long, int>::iterator itr;
     89 void inter(int x,int y){
     90     long long t = ((long double) y - vy * x / (long double)vx) * (long long)1e9;
     91     data[x][y] = (I){t,0};
     92     v[t] = 0;
     93 }
     94 void calc(){
     95     for(int i = 0; i <= n; ++i)
     96         for(int j = 0; j <= n; ++j)
     97             inter(i,j);
     98     for(itr = v.begin(); itr != v.end(); ++itr)
     99         itr->second = ++ct;
    100     for(int i = 0; i <= n; ++i)
    101         for(int j = 0; j <= n; ++j){
    102             data[i][j].rank = v[data[i][j].it];
    103         }
    104 }
    105 long long ans;
    106 void ins(){
    107     sort(g + 1, g + tot + 1, cmp);
    108     for(int i = 1; i <= tot; ++i){
    109         int up = -inf, down = inf;
    110         for(int j = 1; j <= 4; ++j){
    111             int tx = g[i].x + dx[j], ty = g[i].y + dy[j];
    112             up = max(up, data[tx][ty].rank);
    113             down = min(down, data[tx][ty].rank);
    114         }
    115         int r = up - 1, l = down;
    116         if(l <= r && up >= 0){
    117             int t = seg.qer(1, l , r, 1, ct);
    118             ans += max(g[i].height - t, 0LL);
    119             seg.mod(1, l, r, 1, ct, g[i].height);
    120         }
    121     }
    122 }
    123 void spj(){
    124     long long ans = 0;
    125     sort(g + 1, g + tot + 1, cmp);
    126     for(int i = 1; i <= tot; ++i){
    127         int x = g[i].x, y = g[i].y;
    128         data[x][y].it = max(data[x][y].it, data[x+1][y].it);
    129         ans += max(g[i].height - data[x][y].it, 0LL);
    130         data[x][y].it = max(data[x][y].it, g[i].height);
    131     }
    132     cout << ans;
    133 }
    134 int main()
    135 {
    136     freopen("cubes.in","r",stdin);
    137     freopen("cubes.out","w",stdout);
    138     ios::sync_with_stdio(false);
    139     cin >> n >> vx >> vy;
    140     for(int i = 1; i <= n; ++i)
    141         for(int j = 1; j <= n; ++j){
    142             int t; cin >> t;
    143             g[++tot] = (grid){i-1,j-1,t};
    144         }
    145     trans();
    146     calc();
    147     ins();
    148     cout << ans;
    149     return 0;
    150 }
    View Code
  • 相关阅读:
    深入理解浏览器的缓存机制
    【ES6】Set、Map、WeakSet 和 WeakMap 的区别
    js的防抖(debounce) 和 节流(throttling)
    git对比两个分支的差异——git checkout
    纯CSS实现可自定义间距虚线边框
    无语,非也
    Spring AOP
    Spring集成Junit
    Spring注解开发-新注解
    Spring注解开发-原始注解
  • 原文地址:https://www.cnblogs.com/Mr-ren/p/4202338.html
Copyright © 2020-2023  润新知