zoukankan      html  css  js  c++  java
  • 寒假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
  • 相关阅读:
    Mac 终端自动补全忽略大小写
    AtCoder ABC 155F Perils in Parallel
    AtCoder ABC 155E Payment
    AtCoder ABC 155D Pairs
    AtCoder ABC 154F Many Many Paths
    牛客 边界都是1的最大正方形大小
    牛客 打印N个数组整体最大的Top K
    牛客 数组中子数组的最大累乘积
    牛客 在数组中找到一个局部最小的位置
    牛客 子矩阵最大累加和问题
  • 原文地址:https://www.cnblogs.com/OFSHK/p/12483273.html
Copyright © 2011-2022 走看看