HDU 5875Function
Posted fang-hao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5875Function相关的知识,希望对你有一定的参考价值。
题目描述
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:
qwq
You job is to calculate F(l,r), for each query (l,r).
解题思路
我们转化一下题意,询问区间(l ,r)其实就是询问al % al+1 %al+2 %.....%ar 的值,那么,在不断取模的过程中,当前的结果一定是不断变小的,并且如果我们对一个数膜一个比它更大的数,显然这个数是不会变的,也就是说,比当前结果大的数其实对我们没有卵用,所以我们的任务就是在当前位置的后面找到第一个比当前数小的数。 那么,我们应该怎么做呢?
XJH大佬直接给出了做法——st表加二分。我们先维护一个区间最小的st表,然后不断二分,如果当前区间的最小值比当前结果小,那么r=m,否则 l=m+1。我们不断重复操作,那么我们最后就可以得到结果。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int st[100050][25],a[100050]; 7 int loog[100050]; 8 int INF=1000000000; 9 int t,n,m; 10 inline void read(int &x){ 11 x=0; register char ch=getchar(); 12 while(ch<‘0‘||ch>‘9‘)ch=getchar(); 13 while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar(); 14 } 15 inline int query(int x,int y){ 16 int z=loog[y-x+1]; 17 return min(st[x][z],st[y-(1<<z)+1][z]); 18 } 19 int main(){ 20 loog[0]=-1; 21 for(register int i=1;i<=100000;i++)loog[i]=loog[i>>1]+1; 22 read(t); 23 for(register int cas=1;cas<=t;cas++){ 24 for(register int i=0;i<=100000;i++){ 25 for(register int j=0;j<=24;j++){ 26 st[i][j]=INF; 27 } 28 } 29 read(n); 30 int N=loog[n]+1; 31 for(register int i=1;i<=n;i++){ 32 read(a[i]); 33 st[i][0]=a[i]; 34 } 35 for(register int i=1;i<=N;i++){ 36 for(register int j=1;j<=n-(1<<i)+1;j++){ 37 st[j][i]=min(st[j][i-1],st[j+(1<<(i-1))][i-1]); 38 } 39 } 40 read(m); 41 register int l,r; 42 for(register int i=1;i<=m;i++){ 43 read(l),read(r); 44 int num=a[l]; 45 l++; 46 while(l<=r&&query(l,r)<=num){ 47 int tr=r; 48 while(l<tr){ 49 int m=(l+tr)>>1; 50 if(query(l,m)<=num){ 51 tr=m; 52 } 53 else l=m+1; 54 } 55 num%=a[l]; 56 l++; 57 } 58 printf("%d\n",num); 59 } 60 } 61 }
以上是关于HDU 5875Function的主要内容,如果未能解决你的问题,请参考以下文章
Function---hdu5875(大连网选,区间连续求余)