• HDU 5875 Function


    Function

    Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 1095    Accepted Submission(s): 420


    Problem Description
    The shorter, the simpler. With this problem, you should be convinced of this truth.
      
      You are given an array A of N postive integers, and M queries in the form (l,r). A function F(l,r) (1lrN) is defined as:
    F(l,r)={AlF(l,r1) modArl=r;l<r.
    You job is to calculate F(l,r), for each query (l,r).
     
    Input
    There are multiple test cases.
      
      The first line of input contains a integer T, indicating number of test cases, and T test cases follow. 
      
      For each test case, the first line contains an integer N(1N100000).
      The second line contains N space-separated positive integers: A1,,AN (0Ai109).
      The third line contains an integer M denoting the number of queries. 
      The following M lines each contain two integers l,r (1lrN), representing a query.
     
    Output
    For each query(l,r), output F(l,r) on one line.
     
    Sample Input
    1
    3
    2 3 3
    1
    1 3
     
    Sample Output
    2
     
    Source
     
     
     
    解析:题意为对于每个询问区间[l, r],求a[l]%a[l+1]%a[l+2]%...%a[r]。因为当后面的数比前面的数大时,取模得到的结果没有变化。当后面的数比前面的数小或相等时,取模得到的结果才有变化,并且结果越来越小。因此可以进行预处理得到每个数第一个不大于这个数的位置,每次取模时直接跳转到此位置进行。
     
     
     
    #include <cstdio>
    #include <cstring>
    
    const int MAXN = 1e5+5;
    int a[MAXN];
    int next[MAXN]; //第一个小于等于这个数的位置
    int n;
    
    void solve()
    {
        memset(next, -1, sizeof(next)); //初始化为-1
        for(int i = 1; i <= n; ++i){
            for(int j = i+1; j <= n; ++j){
                if(a[j] <= a[i]){
                    next[i] = j;
                    break;
                }
            }
        }
        int q, l, r;
        scanf("%d", &q);
        while(q--){
            scanf("%d%d", &l, &r);
            int res = a[l];
            for(int i = next[l]; i <= r; i = next[i]){
                if(i == -1) //表明后面的数都比它大
                    break;
                if(res == 0)    //0取模后结果还是0
                    break;
                res %= a[i];
            }
            printf("%d
    ", res);
        }
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t--){
            scanf("%d", &n);
            for(int i = 1; i <= n; ++i)
                scanf("%d", &a[i]);
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    JDK下载 安装 配置
    C#中的委托与事件 笔记
    转载 -- C# 中的委托和事件
    Laravel5 路由问题 /home页面无法访问
    eclipse的android智能提示设置
    svn在linux下的使用(ubuntu命令行模式操作svn)
    gdb结合coredump定位崩溃进程
    Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析
    struct的初始化,拷贝及指针成员的使用技巧
    C++ 资源大全
  • 原文地址:https://www.cnblogs.com/inmoonlight/p/5866172.html
Copyright © 2020-2023  润新知