C. Eugene and an array
题意:一个区间中若有一段连续的子区间的区间和为0,则这个区间是 不好的 ,给定一个区间求这个区间内有多少 好 的子区间
想法:一开始想到前缀和,但是发现如果用前缀和的方法暴力去做的话时间复杂度会到O(N^2) 显然会 TLE
我们考虑 f[i] 代表以 i 为结尾的合法序列的个数,先用前缀和的方式进行一个预处理
如果出现了一个区间的区间和为 0 (假设是 l -> r ,并且让这个 l 尽可能大) 那么 sum[r] == sum[l-1]
所以合法的序列的左端点应该从 l + 1 开始
所以我们遇到任何一个点 i 我们应该去找这个 i 之前有没有一段区间和 == sum[i] ,如果有的话那么 我们找到那一段的位置 假设是 1-> j ,那么我们知道 j + 1 -> i 这个区间和是为 0 的,再根据之前的分析我们可以知道左端点应该从 j + 1 + 1 开始。
所以我们需要再用一个 map 去记录 和为 sum[i] 的右端点
那么对于任意一个 i 结尾的序列个数 :
如果 map[sum[i]] 存在 ,那么我们应该更新我们的 maxl ,特别的如果 sum[i] == 0 ,maxl = max(maxl,1)
最终的答案就是 i - (maxl + 1 ) + 1
#pragma GCC optimize(3,"Ofast","inline")//O3优化 #pragma GCC optimize(2)//O2优化 #include <algorithm> #include <string> #include <cstring> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <cmath> #include <cstdio> #include <iomanip> #include <ctime> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) const double eps = 1e-10; const int maxn = 2e5 + 10; const int mod = 998244353; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; LL a[maxn],sum[maxn]; map<LL,int> mapp; int main() { int n; cin >> n; int maxl = 0; LL ans = 0; for (int i = 1;i <= n;i++) { cin >> a[i]; sum[i] = sum[i-1] + a[i]; if (mapp[sum[i]]) maxl = max(maxl,mapp[sum[i]]+1); if (sum[i] == 0) maxl = max(maxl,1); mapp[sum[i]] = i; ans += i - maxl; } cout << ans << endl; return 0; }
我们考虑最多的次数也就是每秒我们只调换一对 MIN
再考虑最少的次数也就是没秒我们尽量调换尽量多的对数 MAX
如果 k < MIN || k > MAX 都是不可以的
否则 我们可以先采取最坏的调换方案直到 k == MIN 的时候,我们就直接采取最优的调换方案就可以了
#pragma GCC optimize(3,"Ofast","inline")//O3优化 #pragma GCC optimize(2)//O2优化 #include <algorithm> #include <string> #include <cstring> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <cmath> #include <cstdio> #include <iomanip> #include <ctime> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) const double eps = 1e-10; const int maxn = 2e5 + 10; const int mod = 998244353; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; int a[maxn],b[maxn],ans[maxn]; char s[maxn]; int cnt; int main() { ios::sync_with_stdio(false); int n,k; scanf("%d %d",&n,&k); scanf("%s",s+1); for (int i = 1;i <= n;i++) { a[i] = (s[i] == 'R' ? 1:-1); b[i] = a[i]; } int Min = 0,Max = 0; while (1) { bool fl = false; for (int i = 1;i < n;i++) { if (a[i] == 1 && a[i+1] == -1) { Max++; swap(a[i],a[i+1]); i++; fl = true; } } if (!fl) break; Min++; } if (k < Min || k > Max) { printf("-1 "); return 0; } while (1) { int i; for (i = 1;i < n;i++) { if (k == Min) break; if (b[i] == 1 && b[i+1] == -1) { k--; swap(b[i],b[i+1]); printf("%d %d",1,i); puts(""); i++; } } cnt = 0; for (;i < n;i++) { if (b[i] == 1 && b[i+1] == -1) { swap(b[i],b[i+1]); ans[cnt++] = i; i++; } } if (cnt) { printf("%d ",cnt); for (i = 0;i < cnt;i++) printf("%d ",ans[i]); puts(""); k--; } Min--; if (k <= 0) break; } return 0; }
F. Kate and imperfection
#pragma GCC optimize(3,"Ofast","inline")//O3优化 #pragma GCC optimize(2)//O2优化 #include <algorithm> #include <string> #include <cstring> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <cmath> #include <cstdio> #include <iomanip> #include <ctime> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) const double eps = 1e-10; const int maxn = 5e5 + 10; const int mod = 998244353; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; int p[maxn],ans[maxn],prime[maxn]; int cnt; void xxs(int lim) { for (int i = 2;i <= lim;i++) { if (!prime[i]) { prime[i] = i;p[cnt++] = i; ans[i] = 1; } for (int j = 0;j < cnt && p[j] <= prime[i] && i * p[j] <= lim;j++) { prime[i * p[j]] = p[j]; ans[i * p[j]] = i; } } } int main() { int n; cin >> n; xxs(n); sort(ans+1,ans+1+n); for (int i = 2;i <= n;i++) { cout << ans[i] << " "; } return 0; }