HDU 5875 Function (单调栈+暴力)

来源:互联网 发布:小米最美女程序员离职 编辑:程序博客网 时间:2024/06/05 10:00


Function

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


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
132 3 311 3
 

Sample Output
2
 

Source
2016 ACM/ICPC Asia Regional Dalian Online

POINT:
用next数组保存比这个数小的数的位置,在循环找下去,找到最小的就是。
法1 单调栈 法2 两个for循环暴力。


法1:
#include <iostream>#include <stdio.h>#include <string.h>#include <stack>using namespace std;int a[100003];int nxt[100003];int main(){    int n;    int T;    scanf("%d",&T);    while(T--)    {        stack<int> q;        while(!q.empty()) q.pop();        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            nxt[i]=-1;            scanf("%d",&a[i]);            while(!q.empty()&&a[q.top()]>=a[i])            {                nxt[q.top()]=i;                q.pop();            }            q.push(i);        }                int m;        scanf("%d",&m);        while(m--)        {            int l,r;            scanf("%d %d",&l,&r);            int now=a[l];            int k=nxt[l];            while(k!=-1&&k<=r)            {                now=now%a[k];                k=nxt[k];            }            printf("%d\n",now);                    }    }            }


法2: 就这个片段不一样。
        for(int i=1;i<=n;i++)        {            for(int j=i+1;j<=n;j++)            {                if(a[i]>=a[j])                {                    nxt[i]=j;                    break;                }            }        }