zoukankan      html  css  js  c++  java
  • 【BZOJ 3476】 线段树===

    59  懒惰的奶牛
    贝西所在的牧场,散落着 N 堆牧草,其中第 i 堆牧草在 ( Xi,Yi ) 的位置,数量有 Ai 个单位。
    贝西从家移动到某一堆牧草的时候,只能沿坐标轴朝正北、正东、正西、正南这四个方向移
    动,所以计算贝西和牧草间的距离时,应采用“曼哈顿距离”—— (x,y ) 和 (x ,y ) 之间的距离为
    |x x | + |y y |。例如贝西的家在 (0.5, 0.3),有一堆牧草在 (3, 2),那么它们之间的距离就是 4.2。
    贝西懒得走动,她想请你为它寻找一个最好的位置作为家,这个家附近距离不超过 K 的牧草数
    量之和是最大的。注意家的坐标可以不是整数,也可以和某堆牧草的坐标完全重合。
    输入格式
    • 第一行:两个整数 N K, 1 N 100000, 1 K 2000000
    • 第二行到第 N + 1 行:第 i + 1 行有三个整数: Ai, Xi Yi, 1 Ai 10000, 0 Xi,Yi
    1000000
    输出格式
    • 单个整数:表示距离和最佳位置不超过 K 的牧草数量之和
    样例输入
    4 3
    7 8 6
    3 0 0
    4 6 0
    1 4 2
    样例输出
    8
    解释
    选择 (3, 0) 为家,位置在 (0, 0), (6, 0) 和
    (4, 2) 的牧草距离家都不超过 K
    来源
    The Lazy Cow, 2014 Mar

    【分析】

      曼哈顿距离的话,那个范围,应该是一个边长和坐标轴呈45度角的正方形。

      这样就有点难搞,难统计。

      我们需要把图形“旋转一下”

      旋转的目标是让正方形的边长平行于坐标轴。、

      那么,观察一下可以得到,可以把nx=x-y ny=x+y 这样就旋转过来了(其实改变了正方形的大小的,但没有关系,只要能判断出曼哈顿距离是不是<=k就好)

     然后就很简单了,用线段树维护y纵坐标,然后x横坐标线性扫描。

    代码如下:

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<cmath>
      8 using namespace std;
      9 #define Maxn 2000010
     10  
     11 struct hp
     12 {
     13     int a,ax,ay;
     14 }tt[Maxn];
     15  
     16 struct node
     17 {
     18     int l,r,lc,rc,ans;
     19     int lazy;
     20 }t[2*Maxn];int len;
     21  
     22 int mymin(int x,int y) {return x<y?x:y;}
     23 int mymax(int x,int y) {return x>y?x:y;}
     24  
     25 bool cmp(hp x,hp y) {return x.ax<y.ax;}
     26 int n,k;
     27  
     28 int build(int l,int r)
     29 {
     30     int x=++len;
     31     t[x].l=l;t[x].r=r;
     32     t[x].ans=0;t[x].lazy=0;
     33     if(l!=r)
     34     {
     35         int mid=(l+r)>>1;
     36         t[x].lc=build(l,mid);
     37         t[x].rc=build(mid+1,r);
     38     }
     39     else t[x].lc=t[x].rc=0;
     40     return x;
     41 }
     42  
     43 void init()
     44 {
     45     scanf("%d%d",&n,&k);
     46     int mx=0;
     47     for(int i=1;i<=n;i++)
     48     {
     49         scanf("%d%d%d",&tt[i].a,&tt[i].ax,&tt[i].ay);
     50         int xx=tt[i].ax;
     51         tt[i].ax=tt[i].ax-tt[i].ay;tt[i].ay=xx+tt[i].ay+1;
     52         mx=mymax(mx,tt[i].ay);
     53     }
     54     sort(tt+1,tt+1+n,cmp);
     55     k=k*2;
     56     build(1,mx);
     57 }
     58  
     59 void upd(int x)
     60 {
     61     if(t[x].lazy==0) return;
     62     t[x].ans+=t[x].lazy;
     63     int lc=t[x].lc,rc=t[x].rc;
     64     if(t[x].l!=t[x].r)
     65     {
     66         t[lc].lazy+=t[x].lazy;
     67         t[rc].lazy+=t[x].lazy;
     68     }
     69     t[x].lazy=0;
     70 }
     71  
     72 void change(int x,int l,int r,int y)
     73 {
     74     if(t[x].l==l&&t[x].r==r)
     75     {
     76         t[x].lazy+=y;
     77         return;
     78     }
     79     upd(x);
     80     int mid=(t[x].l+t[x].r)>>1;
     81     if(r<=mid) change(t[x].lc,l,r,y);
     82     else if(l>mid) change(t[x].rc,l,r,y);
     83     else
     84     {
     85         change(t[x].lc,l,mid,y);
     86         change(t[x].rc,mid+1,r,y);
     87     }
     88     upd(t[x].lc);upd(t[x].rc);
     89     t[x].ans=mymax(t[t[x].lc].ans,t[t[x].rc].ans);
     90 }
     91  
     92 void ffind()
     93 {
     94     int j=0,ans=0;
     95     for(int i=1;i<=n;i++)
     96     {
     97         while(j<n&&tt[j+1].ax-tt[i].ax<=k)
     98         {
     99             int nx=mymax(1,tt[j+1].ay-k);
    100             change(1,nx,tt[j+1].ay,tt[j+1].a);
    101             j++;
    102         }
    103         upd(1);
    104         ans=mymax(ans,t[1].ans);
    105         change(1,mymax(1,tt[i].ay-k),tt[i].ay,-tt[i].a);
    106     }
    107     printf("%d
    ",ans);
    108 }
    109  
    110 int main()
    111 {
    112     init();
    113     ffind();
    114     return 0;
    115 }
    bzoj 3476

    2016-10-31 11:25:57

  • 相关阅读:
    Getting Started with MongoDB (MongoDB Shell Edition)
    Ioc
    BsonDocument
    Find or Query Data with C# Driver
    Insert Data with C# Driver
    Connect to MongoDB
    What's the difference between returning void and returning a Task?
    Import Example Dataset
    jQuery来源学习笔记:整体结构
    Word文件交换的电脑打开字体、排版变化的原因和解决方法!
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6015207.html
Copyright © 2011-2022 走看看