首页 > 代码库 > 区间求最值 线段树
区间求最值 线段树
湖南师范大学 11460 区间求最值
区间求最值 |
Problem description |
给定一个长度为N 的数组,有q个询问,每个询问是求在数组的一段区间内那个元素的因子的个数最大,比如24的因子的个数就是8。 |
Input |
首先是一个整数t,表示有t组测试数据,每组测试数据的第一行是一个整数N(1<=N<=10^6),第二行有N个整数ai(1<=ai<=10^6,i=1,2,.....N)表示数组的元素。第三行有一个整数q(1<=q<=10^5),代表有q个询问,接下来每一行有两个整数,li,ri(li<=ri,li>=1,ri<=N).代表数组的一段区间,并且li+1>=li,ri+1>=ri。 |
Output |
对于每组数据的每个询问都输出一个整数表示在这段区间里面元素因子个数的最大值。 |
Sample Input |
1 10 2 3 5 6 9 11 12 36 39 44 3 2 6 3 8 3 9 |
Sample Output |
4 9 9 |
Problem Source |
zkw线段树:
参考:http://www.cnblogs.com/markliu/archive/2012/05/30/2527020.html
//20716KB 781ms #include <iostream> #include <stdio.h> #include <string.h> using namespace std; #define N 1000010 int T[N*4],M; int yin[N]; void inti() { int i,j; yin[1]=0; for(i=1;i<N;i++) { for(j=i;j<N;j+=i)yin[j]++; } // for(i=0;i<100;i++)printf("%d %d\n",i,yin[i]); } void seg_build(int n){ int i,x; for(M=1;M<=n+1;M*=2); for(i=1+M;i<=n+M;i++){ scanf("%d",&x); T[i]=yin[x]; } for(i=M-1;i;i--) T[i]=max(T[i*2],T[i*2+1]); } int seg_query(int s,int t){ int maxc=-1; for(s=s+M-1,t=t+M+1;s^t^1;s/=2,t/=2){ if(s%2==0) maxc=max(maxc,T[s^1]); if(t%2==1) maxc=max(maxc,T[t^1]); } return maxc; } int main() { inti(); int n,m,a,b; int t; scanf("%d",&t); while(t--){ scanf("%d",&n); memset(T,0,sizeof(T)); seg_build(n); scanf("%d",&m); while(m--){ scanf("%d%d",&a,&b); printf("%d\n",seg_query(a,b)); } } return 0; }
网上题解,想不通为什么这个能过,还比我的省时间
参考:http://blog.csdn.net/u012964281/article/details/29578869
//8864KB 765ms #include <cstdio> #include <cstring> #define maxn 1000005 int find[maxn]; int num[maxn]; int main() { memset(find, 0, sizeof(find)); for (int i = 1; i < maxn; i++){ for (int j = i; j < maxn; j += i) find[j]++; } int t; scanf("%d", &t); while (t--) { int n, q; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &num[i]); scanf("%d", &q); int a, b, ans = -1; int aa, bb, sign; scanf("%d%d", &a, &b); aa = a, bb = b; for (int i = a; i <= b; i++) if (ans < find[num[i]]){ ans = find[num[i]]; sign = i; } printf("%d\n", ans); --q; while (q--) { scanf("%d%d", &a, &b); if (sign >= aa&&sign <= a){ ans = -1; for (int i = a; i <= b; i++) if (ans < find[num[i]]){ ans = find[num[i]]; sign = i; } } else { for (int i = bb; i <= b; i++) if (ans < find[num[i]]){ ans = find[num[i]]; sign = i; } } aa = a, bb = b; printf("%d\n", ans); } } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。