zoukankan      html  css  js  c++  java
  • 【解题报告】编程之美复赛 ——猜数字

    题目连接:http://hihocoder.com/contest/msbop2015round3/problem/2

    大意:给定一个数组,然后有多个查询(l,r,x)求在l~r区间内和x最小的差。

    线段树维护。。。离线操作

    先假定要求的是区间内比x小的数的最小差。那么我们可以从小到大逐个向线段树里面添加数组的值,然后从小到大查询每个查询的结果。

    如:

    数组:[1 8 3 4 9 2 7 6 5] 查询:[(1 9 10)、(3 7 9)、(5 6 5)]

    逐个向线段树里面添加值。

    初始化是0,

    逐个添加1,2,3,4,5

    变成[1,0,3,4,0,2,0,0,5] 这时候执行查询(5,6,5)。线段树维护的是区间最大值。那么这样查询出的结果就是2。也就是说区间5~6内比5小且最大的数是2。取绝对值就是3了。

    离线操作也就是预先读取出全部的查询,按x排序,然后在添加的过程中逐个求出(不是按原来的顺序求),最后再根据输入的顺序输出全部的查询结果。

    以同样的方法可以求出比x大且最小的数。取绝对值再和之前的结果求较小值就是题目要求的查询的结果了。

      1 /*l~r的节点的左孩子是l~(l+r)/2,右孩子是(l+r)/2+1~r*/
      2 #include<stdio.h>
      3 #include<algorithm>
      4 using namespace std;
      5 #define MAXLEN 1500000
      6 typedef int SaveData;/*节点内的储存数据*/
      7 typedef int Point;/*端点下标*/
      8 typedef struct node
      9 {
     10     Point l,r;/*左右端点*/
     11     SaveData value;/*值,如保存和,最值等等*/
     12     /*struct node *pl,*pr; /*链式情况下左右节点指标*/
     13 }SeTree;
     14 SeTree tree[MAXLEN]={0};
     15 SaveData ans;/*返回查询结果*/
     16 /*初始化线段树*/
     17 void bulid(Point v,Point l,Point r)
     18 {
     19     tree[v].l=l;
     20     tree[v].r=r;
     21     if(l==r)
     22     {
     23         tree[v].value=-999999999;
     24         //scanf("%ld",&tree[v].value);
     25         return ;
     26     }
     27     Point mid=(l+r)/2;
     28     bulid(v*2,l,mid);
     29     bulid(v*2+1,mid+1,r);
     30     tree[v].value=max(tree[v*2].value,tree[v*2+1].value);
     31 }
     32 /*更新区间l~r = m*/
     33 SaveData update(Point v,Point l,Point r,SaveData m)
     34 {
     35     SaveData s;
     36     if(tree[v].l==l&&tree[v].r==r)
     37     {
     38         tree[v].value=m;
     39         return m;
     40     }
     41     int mid=(tree[v].l+tree[v].r)/2;
     42     if(r<=mid) {s=update(v*2,l,r,m);}
     43     else
     44     {
     45         if(l>mid) update(v*2+1,l,r,m);
     46         else
     47         {
     48             update(v*2,l,mid,m);
     49             update(v*2+1,mid+1,r,m);
     50         }
     51     }
     52     tree[v].value=max(tree[v*2].value,tree[v*2+1].value);
     53     return s;
     54 }
     55 /*查询l~r*/
     56 void query(Point v,Point l,Point r)
     57 {
     58     if(tree[v].l==l&&tree[v].r==r)
     59     {
     60         ans=max(tree[v].value,ans);/*ans为全局变量*/
     61         return ;
     62     }
     63     int mid=(tree[v].l+tree[v].r)/2;
     64     if(r<=mid)query(v*2,l,r);
     65     else
     66     {
     67         if(l>mid) query(v*2+1,l,r);
     68         else
     69         {
     70             query(v*2,l,mid);
     71             query(v*2+1,mid+1,r);
     72         }
     73     }
     74 }
     75 pair<int,int> sc[200005];
     76 pair<int,pair<pair<int,int>,int> > q[200005];
     77 int ansans[200005];
     78 int t,n,qnum,i,j;
     79 const int INF=1000000000;
     80 int go()
     81 {
     82     bulid(1,1,n);
     83     i=n-1;j=qnum-1;
     84     while(i>=-1&&j>=0)
     85     {
     86         if(i>=0&&sc[i].first>=q[j].first)
     87         {
     88             //printf("up:%d %d
    ",sc[i].second,-sc[i].first);
     89             update(1,sc[i].second,sc[i].second,INF-sc[i].first);
     90             i--;
     91         }
     92         else
     93         {
     94             ans=-9999999999;
     95             //printf("qu:%d %d
    ",q[j].second.first.first,q[j].second.first.second);
     96             query(1,q[j].second.first.first,q[j].second.first.second);
     97             ansans[q[j].second.second]=min(ansans[q[j].second.second],(INF-ans)-q[j].first);
     98             j--;
     99         }
    100     }
    101 }
    102 int main()
    103 {
    104     int cas=1;
    105     scanf("%d",&t);
    106     while(t--)
    107     {
    108         scanf("%d%d",&n,&qnum);
    109         bulid(1,1,n);
    110         for(i=0;i<n;i++)
    111         {
    112             scanf("%d",&sc[i].first);
    113             sc[i].second=i+1;
    114         }
    115         sort(sc,sc+n);
    116         for(i=0;i<qnum;i++)
    117         {
    118             int l,r;
    119             scanf("%d%d%d",&l,&r,&q[i].first);
    120             if(l<=0) l=1;
    121             if(r>n) r=n;
    122             q[i].second.first.first=l;
    123             q[i].second.first.second=r;
    124             q[i].second.second=i;
    125         }
    126         sort(q,q+qnum);
    127         i=0;j=0;
    128         while(i<=n&&j<qnum)
    129         {
    130             if(i<n&&sc[i].first<=q[j].first)
    131             {
    132                 //printf("up:%d %d
    ",sc[i].second,sc[i].first);
    133                 update(1,sc[i].second,sc[i].second,sc[i].first);
    134                 i++;
    135             }
    136             else
    137             {
    138                 ans=-9999999999;
    139                 //printf("qu:%d %d
    ",q[j].second.first.first,q[j].second.first.second);
    140                 query(1,q[j].second.first.first,q[j].second.first.second);
    141                 ansans[q[j].second.second]=q[j].first-ans;
    142                 j++;
    143             }
    144         }
    145         go();
    146         printf("Case #%d:
    ",cas++);
    147         for(i=0;i<qnum;i++)
    148         {
    149             printf("%d
    ",ansans[i]);
    150         }
    151     }
    152     return 0;
    153 }
    View Code
  • 相关阅读:
    视频智能云组网EasyNTS中sqlite和mysql数据库如何进行相互切换?
    关于github上提出EasyRTSPLive视频网关编译过程中修复README错误
    IPC拉转推流场景中如何实现视频网关EasyRTSPLive试用多通道转换?
    如何使用流媒体接入网关实现拉RTSP流转推RTMP流到流媒体服务器?
    视频流媒体平台采用Go语言编程ioutil.ReadAll的用法注意点
    视频流媒体直播平台EasyDSS运行报Only one usage错误原因排查分析
    视频流媒体播放器EasyPlayer.js截取base64编码快照显示不完整问题解决
    视频流媒体RTMP推流组件在Chorme浏览器无法播放FLV匿名直播流问题分析
    视频流媒体直播点播平台如何获取视频转码信息和进度?
    部署国标GB28181流媒体服务器EasyGBS成功后无法播放视频问题步骤排查
  • 原文地址:https://www.cnblogs.com/syiml/p/4490745.html
Copyright © 2011-2022 走看看