zoukankan      html  css  js  c++  java
  • 2016 大连网赛---Function(单调栈)

    题目链接

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5875

    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
     
    Recommend
    wange2014   |   We have carefully selected several similar problems for you:  5877 5876 5874 5873 5872 
     
    题意:一个长度为n的数列,q次询问,每次输入l 和 r 表示一个区间A[l]~A[r]  求A[l]%A[l+1]A[l+2]...A[r];
     
    思路:a%b=r  那么r<a 所以在区间连续取余中 如果一个数对A[i]取完余,后面的数大于A[i],则不用取余,所以只需要找A[i]后小于A[i]且最近的A[j]进行取余,依次进行下去。其实找距离最近且小于自己的数就是 单调栈,这个算法很神奇,复杂度为O(n);
     
    代码如下:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <set>
    using namespace std;
    int A[100005];
    int pos[100005];
    int s[100005];
    
    int main()
    {
        int T,N,M;
        cin>>T;
        while(T--)
        {
            scanf("%d",&N);
            for(int i=1;i<=N;i++)
                scanf("%d",&A[i]);
            int num=1;
            A[N+1]=-1;
            s[1]=N+1;
            for(int i=N;i>=1;i--)///单调栈;
            {
                while(A[i]<A[s[num]]) num--;
                pos[i]=s[num];
                s[++num]=i;
            }
            scanf("%d",&M);
            while(M--)
            {
                int l,r;
                scanf("%d%d",&l,&r);
                int tmp=A[l];
                while(l<=r)
                {
                    if(tmp==0) break;
                    if(pos[l]>r) break;
                    tmp=tmp%A[pos[l]];
                    l=pos[l];
                }
                printf("%d
    ",tmp);
            }
        }
        return 0;
    }
     
     
  • 相关阅读:
    线段树
    数据结构<三> 队列
    数据结构<二>双向链表
    数据结构<一>单链表
    扩展欧几里德算法
    90 个 node.js 扩展模块,我们疯了
    nodejs的查询构造器
    express的路由配置优化
    express路由方案
    Redis学习笔记~目录
  • 原文地址:https://www.cnblogs.com/chen9510/p/5862834.html
Copyright © 2011-2022 走看看