寒假Day49:Get The Treasury

线段树变形~

AC代码:

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<string.h>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 #define inf 0x3f3f3f3f
  8 typedef long long ll;
  9 const int N=1010;
 10 
 11 int y[N<<1],z[N<<1];
 12 
 13 struct node
 14 {
 15     int l,r,c,lf,rf;
 16     int one,two,more;
 17 } tree[N<<3];
 18 
 19 struct Line
 20 {
 21     int f,z1,z2;//f矩形入边左1,出边右-1
 22     int x,up,down;//线段的横坐标、上下纵坐标
 23 } line[N<<1],b[N<<1];
 24 
 25 bool cmp1(Line x,Line y)
 26 {
 27     return x.x<y.x;
 28 }
 29 
 30 void build(int i,int L,int R)
 31 {
 32     tree[i].l=L,tree[i].r=R;
 33     tree[i].c=0;
 34     tree[i].lf=y[L];
 35     tree[i].rf=y[R];
 36     tree[i].one=tree[i].two=tree[i].more=0;
 37     if(L+1==R)
 38         return ;
 39     int mid=(L+R)>>1;
 40     build(i<<1,L,mid);
 41     build(i<<1|1,mid,R);
 42 }
 43 
 44 void pushup(int i)
 45 {
 46     if(tree[i].c>=3)
 47     {
 48         tree[i].more=tree[i].rf-tree[i].lf;
 49         tree[i].one=tree[i].two=0;
 50         //return;
 51     }
 52     else if(tree[i].c==2)//两次
 53     {
 54         if(tree[i].l+1==tree[i].r)
 55         {
 56             tree[i].more=0;
 57             tree[i].two=tree[i].rf-tree[i].lf;
 58             tree[i].one=0;
 59             return;
 60         }
 61         tree[i].more=tree[i<<1].one+tree[i<<1].two+tree[i<<1].more+tree[i<<1|1].one+tree[i<<1|1].two+tree[i<<1|1].more;
 62         tree[i].two=tree[i].rf-tree[i].lf-tree[i].more;
 63         tree[i].one=0;
 64     }
 65     else if(tree[i].c==1)//一次
 66     {
 67         if(tree[i].l+1==tree[i].r)
 68         {
 69             tree[i].more=0;
 70             tree[i].two=0;
 71             tree[i].one=tree[i].rf-tree[i].lf;
 72             return;
 73         }
 74         tree[i].more=tree[i<<1].more+tree[i<<1].two+tree[i<<1|1].more+tree[i<<1|1].two;
 75         tree[i].two=tree[i<<1].one+tree[i<<1|1].one;
 76         tree[i].one=tree[i].rf-tree[i].lf-tree[i].more-tree[i].two;
 77     }
 78     else
 79     {
 80         if(tree[i].l+1==tree[i].r)
 81         {
 82             tree[i].more=tree[i].one=tree[i].two=0;
 83             return;
 84         }
 85         tree[i].more=tree[i<<1].more+tree[i<<1|1].more;
 86         tree[i].two=tree[i<<1].two+tree[i<<1|1].two;
 87         tree[i].one=tree[i<<1].one+tree[i<<1|1].one;
 88     }
 89 }
 90 
 91 void update(int i,Line a)//加入一条新线段、更新线段树
 92 {
 93     if(a.down<=tree[i].lf&&tree[i].rf<=a.up)
 94     {
 95         tree[i].c+=a.f;
 96         pushup(i);
 97         return;
 98     }
 99     if(a.up<=tree[i<<1].rf)
100         update(i<<1,a);
101     else if(a.down>=tree[i<<1|1].lf)
102         update(i<<1|1,a);
103     else
104     {
105         Line b=a;
106         b.up=tree[i<<1].rf;
107         update(i<<1,b);
108         Line c=a;
109         c.down=tree[i<<1|1].lf;
110         update(i<<1|1,c);
111     }
112     pushup(i);
113 }
114 
115 int main()
116 {
117     int t,n,tt=1;
118     scanf("%d",&t);
119     while(t--)
120     {
121         scanf("%d",&n);
122         int k=0;
123         for(int i=1;i<=n;i++)
124         {
125             int x1,y1,z1,x2,up,z2;
126             scanf("%d %d %d %d %d %d",&x1,&y1,&z1,&x2,&up,&z2);
127             line[k].x=x1,line[k].down=y1,line[k].up=up;
128             line[k].z1=z1,line[k].z2=z2;
129             line[k].f=1,y[k]=y1,z[k++]=z1;
130             line[k].x=x2,line[k].down=y1,line[k].up=up;
131             line[k].z1=z1,line[k].z2=z2;
132             line[k].f=-1,y[k]=up,z[k++]=z2;
133         }
134         sort(line,line+k,cmp1);
135         sort(y,y+k);
136         int x=unique(y,y+k)-y;
137         build(1,0,x-1);
138         sort(z,z+k);
139         int xx=unique(z,z+k)-z;
140         ll ans=0;
141         for(int i=0;i<xx-1;i++)
142         {
143             int p=0;
144             for(int j=0;j<k;j++)
145             {
146                 if(line[j].z1<=z[i]&&line[j].z2>z[i])
147                  b[p++]=line[j];
148             }
149             ll w=0;
150             update(1,b[0]);
151             for(int j=1;j<p;j++)
152             {
153                 w+=(ll)tree[1].more*(b[j].x-b[j-1].x);
154                 update(1,b[j]);
155             }
156             ans+=w*(z[i+1]-z[i]);
157         }
158         printf("Case %d: %lld\n",tt++,ans);
159     }
160     return 0;
161 }
View Code
原文地址:https://www.cnblogs.com/OFSHK/p/12483273.html