时间限制: 2000 ms 空间限制: 524288 KB
题目描述
有一个长度为N的序列a[1],a[2]…a[N]。对于一个包含a[L],a[L+1]…a[R]的区间[L,R],小W认为如果存在一个位置a[K]满足区间内所有的数都是a[K]的倍数,那么这个区间是合法的,并且这个区间的价值为R-L,否则这个区间是不合法的。现在小W想知道所有合法的区间中价值最大的区间价值是多少,并且你要告诉他这些区间的左端点(如果有多个区间的价值等于最大值,那么你需要告诉他所有的左端点)。
输入
第一行一个数N,表示数的个数。
第二行N个空格隔开的正整数,表示a[1],a[2]…a[N]。
输出
第一行两个数x,y,分别表示价值最大的区间的个数以及最大价值。
第二行若干个由空格隔开的整数,从小到大输出价值最大的区间的左端点。
样例输入
1 2 3 4 5 6 7 8 9
| 【样例输入1】 5 4 6 9 3 6 【样例输入2】 30 15 15 3 30 9 30 27 11 5 15 20 10 25 20 30 15 30 15 25 5 10 20 7 7 16 2 7 7 28 7
|
样例输出
1 2 3 4 5 6 7
| 【样例输出1】 1 3 2 【样例输出2】 1 13 9
|
数据范围限制
对于30%的数据,满足N<=30,a[i]<=50
对于70%的数据,满足N<=3000,a[i]<=2000
对于100%的数据,满足N<=300000,a[i]<=2000000
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include <bits/stdc++.h> using namespace std; #define mod 1000000007 #define ll long long const int N = 300010; int n; int a[N]; int ans1, ans2; int ans[N]; int main() { freopen("interval.in", "r", stdin); freopen("interval.out", "w", stdout); scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int k = 1; k <= n; k++) { int l, r; for (l = k; l >= 1; l--) if(l == 1 || a[l - 1] % a[k] != 0) break; for (r = k; r <= n; r++) if(r == n || a[r + 1] % a[k] != 0) break; if(ans2 < (r - l)) { ans1 = 1; ans[ans1] = l; ans2 = r - l; } else { if(ans2 == (r - l)) { ans[++ans1] = l; } } } sort(ans + 1, ans + 1 + ans1); ans1 = unique(ans + 1, ans + 1 + ans1) - (ans + 1); printf("%d %d\n", ans1, ans2); for (int i = 1; i <= ans1; i++) printf("%d ", ans[i]); return 0; }
|
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 暗影小站! 注: 本博客暂不开设评论区,请使用邮件119548583@qq.com联系