• 询问任意区间的min,max,gcd,lcm,sum,xor,or,and


    给我们n个数,然后有m个询问,每个询问为L,R,询问区间[L,R]的最大最小值,最小公约数,最大公约数,和,异或,或,且

    这些问题通通可以用RMQ的思想来解决。

    以下用xor来作为例子

    设dp[i][j]为以i开头的,长度为2^j的区间的所有值得异或

    那么dp[i][j] = dp[i][j-1] xor dp[i+(1<<(j-1))][j-1]

    这样,运用动态规划的思想,我们可以在nlogn的时间复杂度内算出以任意点开头的,长度为1,2,4,8...2^j 的区间的异或值。

    那么询问任意区间的异或值时,只要将L->R之间的距离用二进制数来表示,那么只需要log(R-L+1)步就能求出所需的询问。

     1 #include <stdio.h>
     2 #include <string.h>
     3 const int N = 100000 + 10;
     4 int a[N];
     5 int dp[N][30];
     6 int n;
     7 void init()
     8 {
     9     for(int i=1;i<=n;++i)
    10         dp[i][0] = a[i];
    11     for(int j=1;(1<<j)<=n;++j)
    12     {
    13         for(int i=1;i+(1<<j)-1<=n;++i)
    14         {
    15             dp[i][j] = dp[i][j-1] ^ dp[i+(1<<(j-1))][j-1];
    16         }
    17     }
    18 }
    19 
    20 int query(int L, int R)
    21 {
    22     int ans = 0;
    23     int seg = R - L + 1;
    24     int tmp = 1, i = 0;
    25     while(seg)
    26     {
    27         if(seg&1)
    28         {
    29             ans ^= dp[L][i];
    30             L += tmp;
    31         }
    32         seg>>=1;
    33         i++;
    34         tmp = tmp * 2;
    35     }
    36     return ans;
    37 }
    38 int main()
    39 {
    40     while(scanf("%d",&n)!=EOF)
    41     {
    42         for(int i=1;i<=n;++i)
    43             scanf("%d",&a[i]);
    44         init();
    45         int m,L,R;
    46         scanf("%d",&m);
    47         while(m--)
    48         {
    49             scanf("%d%d",&L,&R);
    50             printf("%d
    ",query(L,R));
    51         }
    52     }
    53     return 0;
    54 }
    View Code

    同理,以上所说的其他问题同样能够求解。

    预处理的时间复杂度是O(nlogn), 每次询问是O(logn)

  • 相关阅读:
    Eclipse快捷键大全
    Quartz任务调度快速入门
    Spring整合logback日志
    Java实现二维码的生成与解析
    跨域问题及解决方案
    SpringBoot项目直接在linux下运行
    SpringBoot拦截器中使用RedisTemplate
    Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集
    HDU 4489 The King’s Ups and Downs dp
    HDU 4747 Mex 递推/线段树
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4836397.html
Copyright © 2020-2023  润新知