HDU - 5875 Function —— 预处理?线段树

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lngxling/article/details/82145394

Function

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


 

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≤l≤r≤N) 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≤l≤r≤N), 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

题意:

问L位置的数模L+1,L+2....R的结果是多少

思路:

数模比它大的数是没有意义的,所以只要每次找它后面到R的区间比它小的数,取模后再找比结果更小的数

可以用线段树来查找,预处理的算法最坏情况下是N^2应该是过不了,说明数据比较水 -。-

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
int n,m;
int num[100010];
int to[100010];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(to,-1,sizeof to);
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		scanf("%d",&num[i]);
		for(int i=1;i<=n;i++)
		{
			for(int j=i+1;j<=n;j++)
			{
				if(num[j]<=num[i])
				{
					to[i]=j;
					break;
				}
			}
			if(to[i]==-1)
			to[i]=n;
		}
		to[n]=n+1;
		scanf("%d",&m);
		while(m--)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			int ans=num[x];
			x=to[x];
			while(x<=y)
			{
				ans%=num[x];
				x=to[x];
			}
			printf("%d\n",ans);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/Lngxling/article/details/82145394
今日推荐