• POI2001 金矿


    问题描述

    金矿的老师傅年底要退休了。经理为了奖赏他的尽职尽责的工作,决定在一块包含 n(n ≤ 15000) 个采金点的长方形土地中划出一块长度为 S ,宽度为 W 的区域奖励给他(1 ≤ s , w ≤ 10 000)。老师傅可以自己选择这块地的位置,显然其 中包含的采金点越多越好。你的任务就是计算最多能得到多少个采金点。如果一个采金点的位置在长方形的边上,它也应当被计算在内。

    输入格式

    输入文件的第一行有两个整数,中间用一个空格隔开,表示长方形土地的长和宽即s和w(1<=s,w<=10 000)。第二行有一个整数n(1<=n<=15 000),表示金矿数量。下面的n行与金矿相对应,每行两个整数x和y (-30 000<=x,y<=30 000),中间用一个空格隔开,表示金矿的坐标。

    输出格式

    输出文件只有一个整数,表示选择的最大金矿的数。

    ------------------------------------------------------------

    正解=离散化+平衡树

      点比坐标小的多,离散之- =

      要求一个宽 s 长 w的且覆盖点最多的矩形

      维护一个宽度为  s 的带状区间 既满足宽度限制

      建立以y为关键字的平衡树维护之

      我们要求的既长度h的区间中的最大值

      将一个点x,y 拆成两个点

         x,y,权值为1

         x,y+h+1权值为-1

      维护一个这样的以y为第一关键字,权值为第二关键字的平衡树

      最大前缀和既长度h的区间中的最大值(Orz神差分前缀求和)

    代码如下:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<string>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<cmath>
      7 #include<map>
      8 #include<queue>
      9 #define LL long long
     10 #define INF 999999999
     11 #define Min(num1,num2) if(num1>num2) num1=num2
     12 #define Max(num1,num2) if(num1<num2) num1=num2
     13 #define N 150000
     14 using namespace std ;
     15 struct Point {
     16     int x,y,neg,pos;
     17 }point[N];
     18 bool cmp(const Point &X,const Point &Y){
     19     return X.x<Y.x;
     20 }
     21 struct Tree{
     22     int l,r,f,v1,v2,sum,mmax;
     23 }a[N];
     24 int n,Root,Total,s,w,edge[N],top;
     25 int q[8000];
     26 void puit(int now){
     27     printf("No.%d L:%d R:%d V1:%d V2:%d Sum:%d Mmax:%d
    ",now,a[now].l,a[now].r,a[now].v1,a[now].v2,a[now].sum,a[now].mmax);
     28 }
     29 void update(int now){
     30 //    puit(now);
     31 //    printf("->
    ");
     32 //    puit(a[now].l); 
     33 //    puit(a[now].r);
     34 //    printf("-------------------------------
    ");
     35     a[now].sum=a[a[now].l].sum+a[a[now].r].sum+a[now].v2;
     36     a[now].mmax=max(a[a[now].l].mmax,a[a[now].l].sum+a[now].v2                 );
     37     a[now].mmax=max(a[now].mmax     ,a[a[now].l].sum+a[now].v2+a[a[now].r].mmax);
     38 }
     39 void put(int now){
     40     if(a[now].l) put(a[now].l);
     41     printf("%d ",a[now].v1);
     42     //printf("V1%d(V2%d)(Sum%d)(Mmax%d) ",a[now].v1,a[now].v2,a[now].sum,a[now].mmax);
     43     if(a[now].r) put(a[now].r);
     44 }
     45 void rig(int now){
     46     int f=a[now].f;
     47     a[now].f=a[f].f;
     48     if(a[a[f].f].l==f) a[a[f].f].l=now;
     49     if(a[a[f].f].r==f) a[a[f].f].r=now;
     50     a[f].f=now;
     51     a[f].l=a[now].r;
     52     a[a[now].r].f=f;
     53     a[now].r=f;
     54     update(f);
     55 }
     56 void lef(int now){
     57     int f=a[now].f;
     58     a[now].f=a[f].f;
     59     if(a[a[f].f].l==f) a[a[f].f].l=now;
     60     if(a[a[f].f].r==f) a[a[f].f].r=now;
     61     a[f].f=now;
     62     a[f].r=a[now].l;
     63     a[a[now].l].f=f;
     64     a[now].l=f;
     65     update(f);
     66 }
     67 void splay(int now,int F=0){
     68     while(a[now].f!=F){
     69         int f=a[now].f;
     70         int ff=a[f].f;
     71         if(ff==F)
     72             if(a[f].l==now) 
     73                 rig(now);
     74             else 
     75                 lef(now);
     76         else 
     77             if(a[ff].l==f)
     78                 if(a[f].l==now)
     79                     rig(f),rig(now);
     80                 else 
     81                     lef(now),rig(now);
     82             else
     83                 if(a[f].r==now)
     84                     lef(f),lef(now);
     85                 else
     86                     rig(now),lef(now);
     87     }
     88     update(now);
     89     if(!F) Root=now;
     90 }
     91 int insert(int v1,int v2){
     92     for(int  now=Root;;){
     93         q[++top]=now;
     94         if(v1<a[now].v1||(v1==a[now].v1&&v2<=a[now].v2))
     95              if(a[now].l) now=a[now].l;
     96              else{
     97                 a[now].l=++Total;
     98                 a[Total].v1=v1;
     99                 a[Total].v2=v2;
    100                 a[Total].f=now;
    101                  a[Total].sum=v2;
    102                 a[Total].mmax=max(v2,0);
    103                 break;
    104              }
    105         else 
    106             if(a[now].r) now=a[now].r;
    107             else{
    108                 a[now].r=++Total;
    109                 a[Total].v1=v1;
    110                 a[Total].v2=v2;
    111                 a[Total].f=now;
    112                  a[Total].sum=v2;
    113                  a[Total].mmax=max(v2,0);
    114                  break;
    115             } 
    116     }
    117     while(top) update(q[top--]);
    118     splay(Total);
    119 //    put(Root);
    120 //    printf("
    ");
    121     return Total;
    122 }
    123 int prev(int now){
    124     splay(now);
    125     now=a[now].l;
    126     while(a[now].r) now=a[now].r;
    127     return now;
    128 }
    129 int succ(int now){
    130     splay(now);
    131     now=a[now].r;
    132     while(a[now].l) now=a[now].l;
    133     return now;
    134 }
    135 void del(int now){
    136     int start=prev(now);
    137     int end=succ(now);
    138     splay(start);
    139     splay(end,Root);
    140     a[a[Root].r].l=0;
    141     update(a[Root].r);
    142     update(Root);
    143 }
    144 void removeL(int now){
    145     del(point[now].pos);
    146     del(point[now].neg);
    147 }
    148 void removeR(int now){
    149     point[now].pos=insert(point[now].y     ,1);
    150     point[now].neg=insert(point[now].y+w+1,-1);
    151 }
    152 int main(){
    153     scanf("%d%d%d",&s,&w,&n);
    154     for(int i=1;i<=n;i++)
    155         scanf("%d%d",&point[i].x,&point[i].y);
    156     sort(point+1,point+1+n,cmp);
    157     point[0].x=-INF;
    158     int Maxedge=0;
    159     for(int i=1;i<=n;i++)
    160         if(point[i].x!=point[i-1].x)
    161             edge[++Maxedge]=point[i].x;        
    162     int L=1,now=0,R=1,ans=0;
    163     Total=2;
    164     Root=1;
    165     a[1].v1=INF;
    166     a[2].v1=-INF;
    167     a[1].l=2;
    168     a[2].f=1;
    169     while(now<Maxedge){
    170         ++now;
    171         while(edge[now]-point[L].x>s&&L <=n) removeL(L),++L;
    172         while(point[R].x==edge[now] &&R <=n) removeR(R),++R;
    173         Max(ans,a[Root].mmax);
    174         
    175     }
    176     printf("%d",ans);
    177 }
    View Code
  • 相关阅读:
    多线程篇七:通过Callable和Future获取线程池中单个务完成后的结果
    多线程篇六:线程池
    微服务学习和认识
    多线程篇五:多个线程访问共享对象和数据的方式
    多线程篇四:ThreadLocal实现线程范围内变量共享
    多线程篇三:线程同步
    多线程篇二:定时任务
    多线程篇一:传统线程实现方式
    Jms学习篇二:ActiveMQ
    04-运算符
  • 原文地址:https://www.cnblogs.com/Blacko/p/3449193.html
Copyright © 2020-2023  润新知