首页 > 代码库 > hdu 3642 Get The Treasure

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\n",cas++,ans);
135     }
136     return 0;
137  } 

 

hdu 3642 Get The Treasure