1. 程式人生 > >Codeforces Round #323 (Div. 2) E - Superior Periodic Subarrays

Codeforces Round #323 (Div. 2) E - Superior Periodic Subarrays

esp second code n) ace namespace fine first make

E - Superior Periodic Subarrays

好難的一題啊。。。

這個博客講的很好,搬運一下。

https://blog.csdn.net/thy_asdf/article/details/49406133

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define piii pair<int, pair<int,int> >

using
namespace std; const int N = 2e5 + 10; const int M = 10 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; int gcd(int a, int b) { return !b ? a : gcd(b, a % b); } int n, mx, a[N << 1], cnt[N << 1], f[N << 1
]; bool flag[N << 1]; int main() { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); a[i + n] = a[i]; } LL ans = 0; for(int d = 1; d < n; d++) { //枚舉GCD(n,s) if(n % d) continue; memset(flag, false
, sizeof(flag)); for(int k = 0; k < d; k++) { //枚舉起點 mx = 0; for(int i = k; i < 2 * n; i += d) mx = max(mx, a[i]); //找出這些相隔為d的數之間最大的數 for(int i = k; i < 2 * n; i += d) flag[i] = (a[i] == mx);//判斷這個數是不是一系列數的最大值 } f[0] = flag[0]; //以i結尾的"卓越子序列"最長可能長度 for(int i = 1; i < 2 * n; i++) { if(flag[i]) f[i] = f[i - 1] + 1; else f[i] = 0; f[i] = min(f[i], n - 1); } cnt[0] = 0; //1-i中有多少個數與n的gcd為枚舉的d for(int i = 1; i < n / d; i++) cnt[i] = cnt[i - 1] + (gcd(i, n / d) == 1); //要把Gcd(s,n)==d化簡成gcd(s/d,n/d)==1,不然會被卡 for(int i = n; i < n * 2; i++) ans += cnt[f[i] / d]; } printf("%lld\n", ans); return 0; } /* */

Codeforces Round #323 (Div. 2) E - Superior Periodic Subarrays