zoukankan      html  css  js  c++  java
  • hdu 3642 Get The Treasure

      对于这题,一开始看到z值较小,就像枚举z坐标,然后对于一个单独的z平面做面积交来累加答案。。(三个以上柱体的体积交)

      搜题解学完up函数的姿势后感觉自己写的还是蛮不错的嘛。。

      线段树每个节点包含当前节店的覆盖次数cnt,表示覆盖次数-长度映射的数组,由于只要cnt>=3就可以统计,故数组只开到3。。

      由于n只有1000,所以平面交的时候先对于x坐标进行离散化,然后就是扫描线。。

      一开始自己的姿势是对于每个z建立一个线段树,但是会mle。。。后来才改成使用一个重复利用。。然后就是没注意到cnt会大于三可能会re到无法自拔(比如我)。。

      

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define ll long long
      4 #define inf 0x3f3f3f3f
      5 #define mod 1000000007
      6 #define LL 2*n
      7 #define RR 2*n+1
      8 #define lson l,mid,2*n
      9 #define rson mid+1,r,2*n+1
     10 #define mlt map<ll,ll>::iterator
     11 #define mit map<int,int>::iterator
     12 #define vi vector<int>
     13 #define mii map<int,int>
     14 #define msi map<string,int>
     15 #define si set<int>
     16 #define sit set<int>::iterator
     17 #define slt set<l>::iterator
     18 #define mp make_pair
     19 #define pb push_back
     20 #define pii pair<int,int>
     21 #define pdd pair<double,double>
     22 #define pi acos(-1)
     23 const int maxn =2222;
     24 struct Seg{
     25     int l , r , h , s;
     26     Seg() {}  
     27     Seg(ll a,ll b,ll c,ll d):l(a) , r(b) , h(c) , s(d) {}
     28     bool operator < (const Seg &cmp) const {
     29     if (h == cmp.h) return s > cmp.s;
     30     return h < cmp.h;
     31     }
     32 }ss[maxn<<2];
     33 int x[maxn<<2];
     34 struct node
     35 {
     36     int cnt,a[5];
     37 }tr[maxn<<2];
     38 int bin(int z,int n)
     39 {
     40     int l=0,r=n;
     41     while(r-l>1)
     42     {
     43         int mid=(l+r)>>1;
     44         if(x[mid]>=z)
     45         r=mid;
     46         else
     47         l=mid;
     48     }
     49     return r;
     50 }
     51 void up(int l,int r,int n)
     52 {
     53     memset(tr[n].a,0,sizeof(tr[n].a));
     54     int cnt=min(3,tr[n].cnt);
     55     if(l==r)
     56     {
     57         tr[n].a[cnt]=x[r+1]-x[l];
     58         return;
     59     }
     60     int tmp=x[r+1]-x[l];
     61     for(int i=0;i<=3;i++)
     62     {
     63         tr[n].a[min(cnt+i,3)]+=tr[LL].a[i]+tr[RR].a[i];
     64     }
     65     for(int i=0;i<=3;i++)
     66     tmp-=tr[n].a[i];
     67     tr[n].a[cnt]+=tmp;
     68 }
     69 void update(int l,int r,int n,int left,int right,int targ)
     70 {
     71     if(left<=l&&r<=right)
     72     {
     73         tr[n].cnt+=targ;
     74         up(l,r,n);
     75         return ;
     76     }
     77     int mid=(l+r)>>1;
     78     if(left<=mid)
     79     update(lson,left,right,targ);
     80     if(right>mid)
     81     update(rson,left,right,targ);
     82     up(l,r,n);
     83 }
     84 int a[5000][20];
     85 int main()
     86 {
     87     int t,cas=1;
     88    //freopen("C:\Users\Administrator\Documents\duipai\data.txt","r",stdin);freopen("C:\Users\Administrator\Documents\duipai\out1.txt","w",stdout);
     89     scanf("%d",&t);
     90     while(t--)
     91     {
     92         int n;
     93         scanf("%d",&n);
     94         for(int i=1;i<=n;i++)
     95         {
     96             for(int j=1;j<=6;j++)
     97             scanf("%d",&a[i][j]);
     98         }
     99         ll ans=0;
    100         for(int i=-500;i<=500;i++)
    101         {
    102             int num1=0,num=0;
    103             for(int k=1;k<=n;k++)
    104             {
    105                     if(i>=a[k][3]&&i<a[k][6])
    106                     {
    107                         ss[++num]=Seg(a[k][1],a[k][4],a[k][2],1);
    108                         ss[++num]=Seg(a[k][1],a[k][4],a[k][5],-1);
    109                     }
    110             }
    111             sort(ss+1,ss+1+num);
    112             for(int j=1;j<=num;j++)
    113             {
    114                 x[++num1]=ss[j].l;
    115                 x[++num1]=ss[j].r;
    116             }
    117             sort(x+1,x+1+num1);
    118             int tmp=1;
    119             for(int j=2;j<=num1;j++)
    120             {
    121                 if(x[j]!=x[j-1])
    122                 x[++tmp]=x[j];
    123             }
    124             num1=tmp;
    125             for(int j=1;j<=num;j++)
    126             {
    127                 int l=bin(ss[j].l,num1);
    128                 int r=bin(ss[j].r,num1)-1;
    129                 if(l<=r)
    130                 update(1,num1-1,1,l,r,ss[j].s);
    131                 ans+=1ll*tr[1].a[3]*(ss[j+1].h-ss[j].h);
    132             }
    133         }
    134         printf("Case %d: %I64d
    ",cas++,ans);
    135     }
    136     return 0;
    137  } 
  • 相关阅读:
    HDU
    POJ-1325 Machine Schedule 二分图匹配 最小点覆盖问题
    HDU- 6437.Videos 最“大”费用流 -化区间为点
    曼哈顿最小生成树 全网最全
    牛客 136G-指纹锁 set容器重载
    牛客 136J-洋灰三角 +高中数学博大精深
    数学:矩阵快速幂
    数学:Burnside引理与Pólya定理
    数据结构:树上分块
    数据结构:Bitset
  • 原文地址:https://www.cnblogs.com/julyc/p/6498062.html
Copyright © 2011-2022 走看看