zoukankan      html  css  js  c++  java
  • HDU 5875 Function RMQ+二分

    题目大意:

    定义F(l,r) :如果l==r F(l,r)=a[l] 否则 F[l,r]=a%al+1%al+2%...%ar

    数据范围为N<=1e5,M<=1e5

    解法:

    注意到a%b,如果a<b 那么模不模b没有影响。而且一个数要进行取模的操作次数是不会很多的。所以问题再与怎么快速找到要模上哪些数。

    我们要快速找到小于等于当前值的小下标,对它取模后,不断的重复这个操作。

    我们先用RMQ预处理出ST表,query函数返回的是[l,r]区间内的最小值的下标。

    代码:

     

     1 #include<cstdio>
     2 #include<cstring>
     3 #define min(a,b) (a<b?a:b)
     4 #define max(a,b) (a>b?a:b)
     5 using namespace std;
     6 const int MAXN=1e5+7;
     7 int a[MAXN],dp[MAXN][25];
     8 int N,M;
     9 void init_rmq()//dp[i][j]:在[i,i+(1<<j)]区间内a[k]最小值得下标
    10 {
    11     for(int i=1;i<=N;++i)dp[i][0]=i;
    12     for(int j=1;(1<<j)<=N;++j)
    13     {
    14         for(int i=1;i+(1<<j)-1<=N;++i)
    15         {
    16             int x=dp[i][j-1];
    17             int y=dp[i+(1<<(j-1))][j-1];
    18             dp[i][j]= a[x]<a[y]?x:y;
    19         }
    20     }
    21 }
    22 int query(int l,int r)//返回[l,r]区间最小值对应得下标
    23 {
    24     int len=r-l+1;
    25     int k=0;
    26     while((1<<k)<=len)++k;--k;
    27     int x=dp[l][k],y=dp[r-(1<<k)+1][k];
    28     return a[x]<a[y]?x:y;
    29 }
    30 int main() {
    31     int T;scanf("%d",&T);
    32     while(T--)
    33     {
    34         memset(a,0,sizeof(a));
    35         memset(dp,0,sizeof(dp));
    36         scanf("%d",&N);
    37         for(int i=1;i<=N;++i)scanf("%d",&a[i]);
    38         scanf("%d",&M);
    39         init_rmq();
    40         while(M--)
    41         {
    42             int l,r;scanf("%d%d",&l,&r);
    43             if(l==r)
    44             {
    45                 printf("%d
    ",a[l]);
    46                 continue;
    47             }
    48             int val=a[l];
    49             int begin=l+1-1,right=r;
    50             for(;begin<right;)
    51             {
    52                 int lo=begin,hi=right;
    53                 while(hi-lo>1)
    54                 {
    55                     int m=(hi+lo)/2;
    56                     int x=query(begin,m);//[lo,m];
    57                     if(a[x]<=val)hi=m;
    58                     else lo=m;
    59                 }
    60                 val%=a[hi];
    61                 begin=hi;
    62             }
    63             printf("%d
    ",val);
    64         }
    65     }
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    Java 第十一届 蓝桥杯 省模拟赛 螺旋矩阵
    Java 第十一届 蓝桥杯 省模拟赛 螺旋矩阵
    Java 第十一届 蓝桥杯 省模拟赛 正整数的摆动序列
    Java 第十一届 蓝桥杯 省模拟赛 正整数的摆动序列
    Python abs() 函数
    Python数学常量
    Python三角函数
    Python随机数函数
    Python数学函数
    语义分割模型优化
  • 原文地址:https://www.cnblogs.com/sun-yinkai/p/7700714.html
Copyright © 2011-2022 走看看