HDU 5875 Function 單調棧 + 技巧 區間和

                                                    Function

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


 

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) (1≤lrN) is defined as:
F(l,r)={AlF(l,r−1) 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(1≤N≤100000).
  The second line contains N space-separated positive integers: A1,…,AN (0≤Ai≤109).
  The third line contains an integer M denoting the number of queries.
  The following M lines each contain two integers l,r (1≤lrN), 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

 

解析

因爲%在不斷地有效的取餘是最多取餘lgmax(Ai)  (約等於 32) 次,所以只要用單調棧預處理出一個next數組記錄比當前數小或等於的位置,然後 對於每次l,r 查詢, 從l 開始跳轉,不斷跳轉比當前數小的值

這題也可以用線段樹,先查詢l+1 ~ r中 比a[l] 小的第一個值

 

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 1e5+100;
const int INF = 0x3f3f3f3f;

int n,T;
int a[maxn],child[maxn];
stack <int> s;
int main()
{
  scanf("%d",&T);
  while(T--)
  {
    scanf("%d",&n);
    for(int i = 0; i < n; i++)  scanf("%d",&a[i]);
    while(!s.empty())  s.pop();
    memset(child,-1,sizeof(child));
    for(int i = 0; i < n; i++)
    {
      while(!s.empty() && a[s.top()] >= a[i]) {child[s.top()] = i;s.pop();}
      s.push(i);
    }
    int q;
    scanf("%d",&q);
    while(q--)
    {
      int l,r;
      scanf("%d%d",&l,&r);
      l--,r--;
      if(l == r)  printf("%d\n",a[l]);
      else
      {
        int t = child[l];
        int ans = a[l];
        while(t != -1 && t <= r && t < n)
        {
           ans %= a[t];
           t = child[t];
        }
       printf("%d\n",ans);
      }
    }
  }
  return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章