zoukankan      html  css  js  c++  java
  • poj 3368

    题目:http://poj.org/problem?id=3368

    题意:给定n个数,给出一段区间,问区间内相同数最多的有一个

    思路:首先把给的数进行处理,给n个数重新编号,相同的数编号相同,用结构体记录相同数在原数组中的左右位置,用一个辅助数组记录原数据对应的新编号,询问的时候去看给的区间对应到新编号里面的位置

    View Code
      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <math.h>
      5 #define N 100010
      6 #define _clr(a,val) (memset(a,val,sizeof(a)))
      7 
      8 using namespace std;
      9 
     10 int a[N],hash[N],mx[25][N];
     11 struct node
     12 {
     13     int l,r;
     14 }p[N];
     15 int n,q,len;
     16 void rmqinit()
     17 {
     18     int i,j;
     19     for (i = 1; (1 << i) <= len; ++i)
     20     {
     21         for (j = 0; (j + (1 << (i - 1))) <= len; ++j)
     22         {
     23             mx[i][j] = max(mx[i-1][j],mx[i-1][j + (1 << (i - 1))]);
     24         }
     25     }
     26 }
     27 int rmqmax(int s,int e)
     28 {
     29     int k = log(1.0*(e - s + 1))/log(2.0);
     30     return max(mx[k][s],mx[k][e - (1 << k) + 1]);
     31 }
     32 void change()  //预处理
     33 {
     34     int i;
     35     i = 1;
     36     len = 0;
     37     while(i <= n)
     38     {
     39         int tem = N;
     40         int ans = 0;
     41         if(tem != a[i])
     42         {
     43             int temp = i;
     44             p[len].l = i;
     45             tem = a[temp++];
     46             hash[i] = len;
     47             ans ++;
     48             while(tem == a[temp])
     49             {
     50                 hash[temp++] = len;
     51                 ans++;
     52             }
     53             mx[0][len] = ans;
     54             p[len].r = temp - 1;
     55             len++;
     56             i = temp;
     57         }
     58     }
     59 }
     60 void slove(int s,int e)
     61 {
     62     if (hash[s] == hash[e]) // 如果对应的新标号相同,则直接输出个数
     63     {
     64         printf("%d\n",e - s + 1);
     65     }
     66     else if (hash[s] + 1 == hash[e])  // 如果恰好横跨两个区间,那么计算个数多的
     67     {
     68         printf("%d\n",max(p[hash[s]].r - s + 1,e - p[hash[e]].l + 1));
     69     }
     70     else  // 否则就用rmq来计算区间最值
     71     {
     72            int max1 = p[hash[s]].r - s + 1;
     73            int max2 = e - p[hash[e]].l + 1;
     74            int max3 = rmqmax(hash[s] + 1,hash[e] - 1);
     75            printf("%d\n",max(max(max1,max2),max3));
     76     }
     77 }
     78 int main()
     79 {
     80     int i,s,e;
     81     //freopen("data.txt","r",stdin);
     82     while (scanf("%d",&n))
     83     {
     84         if (!n) break;
     85         _clr(p,0);
     86         scanf("%d",&q);
     87         for (i = 1; i <= n; ++i)
     88         {
     89             scanf("%d",&a[i]);
     90         }
     91         change();
     92         rmqinit();
     93         while (q--)
     94         {
     95             scanf("%d%d",&s,&e);
     96             slove(s,e);
     97         }
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    World Wind Java开发之一(转)
    Excel如何显示隐藏列?
    Oracle开发›如何取出每个分组的第一条记
    如何解决EXCEL中的科学计数法
    使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10
    POI读取单元格信息及单元格公式
    java中判断字符串是否为数字的方法的几种方法
    阿里云OSS的 存储包、下行流量包、回流流量包 三者有啥关系
    vue+datatable+vue-resource动态获取jsonp数据2
    vue+datatable+vue-resource动态获取jsonp数据
  • 原文地址:https://www.cnblogs.com/fxh19911107/p/2616576.html
Copyright © 2011-2022 走看看