HDU 5785 Function 倍增 (2016 ACM/ICPC Asia Regional Dalian Online)
Posted Coolxxx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5785 Function 倍增 (2016 ACM/ICPC Asia Regional Dalian Online)相关的知识,希望对你有一定的参考价值。
Function
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 976 Accepted Submission(s): 375Problem DescriptionThe 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).
InputThere 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.
OutputFor each query(l,r), output F(l,r) on one line.
Sample Input1 3 2 3 3 1 1 3
Sample Output2
Source
Recommend
Statistic | Submit | Discuss | Note
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5875
题目大意:
N个数(N<=100000),M个询问,每次询问L,R,求F(L,R)。
F(L,R)=F(L,R-1)%A[R] , L<R
=A[L] , L=R
题目思路:
【倍增】
这题数据水到暴力居然过了。。比赛的时候一想会T就没写。
首先这题实际是求A[L]%A[L+1]%A[L+2]...%A[R]的值。
那么很容易想到A[L]右边比他大的数都是没有必要取模的,变为找L右边第一个小于A[L]的取模
模完后的结果缩小,再次寻找当前位置右边第一个小于此时的值的继续取模。可以证明这样的取模次数为log2N(100000取模后最大为49999)
暴力的做法就是预处理的时候直接从后往前用单调栈求出位置X右边第一个小于A[X]的位置Y,next[X]=Y。查询的时候用next跳着模。
当然这是不够的,因为可以构造出递减序列使得实际操作次数仍为N。
用倍增的思想,对于位置i右侧的最长下降子序列,next[i][j]表示位置i右边第2j个的位置,预处理出每个位置的next数组
每次做的时候尽量远跳,直到找到next[j][0]恰好小于当前的值z,则z对A[next[j][0]]取模,移动左标记,继续查找,直到超出R或者没有更小的数。
倍增:
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<stack> 10 #include<queue> 11 #include<set> 12 #include<bitset> 13 #include<memory.h> 14 #include<time.h> 15 #include<stdio.h> 16 #include<stdlib.h> 17 #include<string.h> 18 //#include<stdbool.h> 19 #include<math.h> 20 #define min(a,b) ((a)<(b)?(a):(b)) 21 #define max(a,b) ((a)>(b)?(a):(b)) 22 #define abs(a) ((a)>0?(a):(-(a))) 23 #define lowbit(a) (a&(-a)) 24 #define sqr(a) ((a)*(a)) 25 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 26 #define mem(a,b) memset(a,b,sizeof(a)) 27 #define eps (1e-10) 28 #define J 10000 29 #define mod 1000000007 30 #define MAX 0x7f7f7f7f 31 #define PI 3.14159265358979323 32 #pragma comment(linker,"/STACK:1024000000,1024000000") 33 #define N 100004 34 #define M 18 35 using namespace std; 36 typedef long long LL; 37 double anss; 38 LL aans; 39 int cas,cass; 40 int n,m,lll,ans; 41 int a[N],s[N]; 42 int nextt[N][M]; 43 void init() 44 { 45 int i,j,k,top; 46 s[top=1]=n; 47 for(i=0;i<M;i++)nextt[n][i]=n+1; 48 for(i=n-1;i;i--) 49 { 50 while(top && a[i]<a[s[top]])top--; 51 if(!top)nextt[i][0]=n+1; 52 else nextt[i][0]=s[top]; 53 s[++top]=i; 54 } 55 for(j=1;j<M;j++) 56 { 57 for(i=1;i<n;i++) 58 { 59 k=nextt[i][j-1]; 60 nextt[i][j]=nextt[k][j-1]; 61 } 62 } 63 } 64 int work(int l,int r) 65 { 66 int i,j,z=a[l]; 67 if(l==r)return z; 68 while(l<r) 69 { 70 if(!z)return z; 71 for(i=0;i<M-1;i++) 72 { 73 if(a[nextt[l][0]]<=z || nextt[l][i]>r)break; 74 if(a[nextt[l][i+1]]<=z || nextt[l][i+1]>r) 75 { 76 l=nextt[l][i]; 77 i=-1; 78 continue; 79 } 80 } 81 if(i==M || nextt[l][i]>r || !a[nextt[l][i]])return z; 82 z%=a[nextt[l][0]];l=nextt[l][0]; 83 } 84 return z; 85 } 86 int main() 87 { 88 #ifndef ONLINE_JUDGE 89 // freopen("1.txt","r",stdin); 90 // freopen("2.txt","w",stdout); 91 #endif 92 int i,j,k; 93 int x,y,z; 94 // init(); 95 for(scanf("%d",&cass);cass;cass--) 96 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 97 // while(~scanf("%s",s)) 98 // while(~scanf("%d",&n)) 99 { 100 scanf("%d",&n); 101 for(i=1;i<=n;i++)scanf("%d",a+i); 102 init(); 103 scanf("%d",&m); 104 for(i=1;i<=m;i++) 105 { 106 scanf("%d%d",&x,&y); 107 printf("%d\n",work(x,y)); 108 } 109 } 110 return 0; 111 } 112 /* 113 // 114 115 // 116 */
暴力:
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<stack> 10 #include<queue> 11 #include<set> 12 #include<bitset> 13 #include<memory.h> 14 #include<time.h> 15 #include<stdio.h> 16 #include<stdlib.h> 17 #include<string.h> 18 //#include<stdbool.h> 19 #include<math.h> 20 #define min(a,b) ((a)<(b)?(a):(b)) 21 #define max(a,b) ((a)>(b)?(a):(b)) 22 #define abs(a) ((a)>0?(a):(-(a))) 23 #define lowbit(a) (a&(-a)) 24 #define sqr(a) ((a)*(a)) 25 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 26 #define mem(a,b) memset(a,b,sizeof(a)) 27 #define eps (1e-10) 28 #define J 10000 29 #define mod 1000000007 30 #define MAX 0x7f7f7f7f 31 #define PI 3.14159265358979323 32 #pragma comment(linker,"/STACK:1024000000,1024000000") 33 #define N 100004 34 using namespace std; 35 typedef long long LL; 36 double anss; 37 LL aans; 38 int cas,cass; 39 int n,m,lll,ans; 40 int a[N],pre[N],s[N]; 41 void print() 42 { 43 int i; 44 for(i=1;i<=n;i++) 45 printf("%d ",pre[i]); 46 puts(""); 47 } 48 int main() 49 { 50 #ifndef ONLINE_JUDGE 51 // freopen("1.txt","r",stdin); 52 // freopen("2.txt","w",stdout); 53 #endif 54 int i,j,k; 55 int x,y,z,top,l,r; 56 // init(); 57 for(scanf("%d",&cass);cass;cass--) 58 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 59 // while(~scanf("%s",s)) 60 // while(~scanf("%d",&n)) 61 { 62 scanf("%d",&n); 63 for(i=1;i<=n;i++) 64 { 65 scanf("%d",&a[i]); 66 } 67 top=1; 68 s[top]=n;pre[n]=n+1; 69 for(i=n-1;i;i--) 70 { 71 while(top && a[i]<=a[s[top]]) 72 top--; 73 if(!top)pre[i]=n+1; 74 else pre[i]=s[top]; 75 s[++top]=i; 76 } 77 scanf("%d",&m); 78 for(i=1;i<=m;i++) 79 { 80 scanf("%d%d",&l,&r); 81 x=a[l]; 82 for(j=pre[l];j<=r;j=pre[j]) 83 x%=a[j]; 84 printf("%d\n",x); 85 } 86 //print(); 87 } 88 return 0; 89 } 90 /* 91 // 92 93 // 94 */
以上是关于HDU 5785 Function 倍增 (2016 ACM/ICPC Asia Regional Dalian Online)的主要内容,如果未能解决你的问题,请参考以下文章