《武汉大学2020年新生程序设计竞赛》
A:签到。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<string,string> pii; const int N = 1e5+5; const int M = 1e6+5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } } using namespace FASTIO; int w[105]; int main() { int ca;ca = read(); while(ca--) { int n,m;n = read(),m = read(); for(int i = 1;i <= n;++i) w[i] = read(); sort(w + 1,w + n + 1); double ma = m; int f = 0; for(int i = 1;i <= n;++i) { if(ma >= w[i]) { ma -= w[i] * 0.7; } else f = 1; } printf("%s\n",f ? "no" : "yes"); } return 0; }
C:签到
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<string,string> pii; const int N = 1e5+5; const int M = 1e6+5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } } using namespace FASTIO; int main() { int n;n = read(); while(n--) { string s;cin >> s; int len = 0,ans = 0; for(auto v : s) { if(v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u') len++; else len = 0; ans = max(ans,len); } printf("%d\n",ans); } return 0; }
J:记录一下头两个刚好卡住爆杀的位置,然后讨论下即可。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<string,string> pii; const int N = 1e3+5; const int M = 1e6+5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } } using namespace FASTIO; int h[N]; int main() { int n,a,k;n = read(),a = read(),k = read(); for(int i = 1;i <= n;++i) h[i] = read(); int ans = 0,tag = 0,pre = 0,f = 0; for(int i = 1;i <= n;++i) { if(h[i] == k) { if(tag == 1){ans = i;break;} else if(tag == 0) { if(i == n){ans = i;break;} pre = i; } tag++; } else if(h[i] > k) { if(tag == 0) { int j = i + 1; while(j <= n && h[j] < k) j++; if(j > n) ans = n; else if(h[j] == k) ans = j; else ans = j - 1; } else if(tag == 1) ans = pre + 1; break; } else f++; } if(f == n) ans = n; printf("%d\n",ans); return 0; }
D:记录0的位置,然后枚举开始二分找答案即可
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<string,string> pii; const int N = 1e6+5; const int M = 1e6+5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } } using namespace FASTIO; int a[N],b[N]; int main() { int n;n = read(); while(n--) { string s;cin >> s; int k;k = read(); if(k == 0) { int len = 0,ans = 0; for(auto v : s) { if(v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u') len++; else len = 0; ans = max(ans,len); } printf("%d\n",ans); } else { int cnt = 0; for(int i = 0;i < s.size();++i) { if(s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') a[i + 1] = 1; else a[i + 1] = 0,b[++cnt] = i + 1; } int ans = 0; for(int i = 1;i <= s.size();++i) { int tmp; if(a[i] == 1) { int pos = upper_bound(b + 1,b + cnt + 1,i) - b; if(pos > cnt) tmp = s.size() - i + 1; else { int ma = b[pos + k]; if(pos + k > cnt) tmp = s.size() - i + 1; else tmp = ma - i; } } else { int pos = lower_bound(b + 1,b + cnt + 1,i) - b,ma; if(pos + k > cnt) ma = s.size(); else ma = max(b[pos + k - 1],b[pos + k] - 1); tmp = ma - i + 1; } // printf("i is %d tmp is %d\n",i,tmp); ans = max(ans,tmp); } printf("%d\n",ans); } } return 0; }
E:非常好的一道题。第一眼觉得是主席树,但是没想出来。
赛后看了大佬们的思路,居然是分块(妙啊
思路:考虑到分块后复杂度为 330 * 1e5,那么复杂度还是够得 。
首先,我们考虑一下询问,因为每个块最多只有330多。
那么当两个询问是相邻块或者在同一个块中时,直接暴力去统计即可。
当不是的时候,我们可以预处理出中间所有完整的块里的最值。
那么,如果中间的块价值要加上首尾两个不完整的块的话。
那个最大值只可能是在首尾的两个块中,所以我们再去看看首尾块中的值是否会比中间的最大值大。
那么,显然首尾块中的个数,要加上中间的个数,所以这里记录一个前缀和即可O(1)求出。
注意每次统计完次数后,都需要减去。
中间的最值统计写错,调了很久,最后造了下数据才测出来。
一开始是这样求的块之间最值:
for(int i = 1;i <= bel[n];++i) { for(int j = L[i];j <= n;++j) { cnt[a[j]]++; mx[i][bel[j]] = max(mx[i][bel[j]],b[a[j]] * cnt[a[j]]); } for(int j = L[i];j <= n;++j) cnt[a[j]]--; }
但是后面发现,这样只有在遇到最值的时候才会更新到最值,如果那个块里没有那个最值,那么就更新不到了。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5+5; const int M = 1e6+5; const LL Mod = 998244353; #define pi acos(-1) #define INF 1e18 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();} return x * f; } } using namespace FASTIO; LL a[N],b[N],mx[405][405],cnt[N],sum[405][N]; int L[405],r[405],bel[N]; int main() { int n,m;n = read(),m = read(); int tot = 0; for(int i = 1;i <= n;++i) a[i] = read(),b[++tot] = a[i]; sort(b + 1,b + tot + 1); int len = unique(b + 1,b + tot + 1) - b - 1; int blsize = sqrt(n); for(int i = 1;i <= n;++i) bel[i] = (i - 1) / blsize + 1; for(int i = 1;i <= n;++i) a[i] = lower_bound(b + 1,b + len + 1,a[i]) - b; for(int i = 1;i <= bel[n];++i) { L[i] = blsize * (i - 1) + 1; r[i] = min(blsize * i,n); } for(int i = 1;i <= n;++i) sum[bel[i]][a[i]]++; for(int i = 1;i <= bel[n];++i) for(int j = 1;j <= len;++j) sum[i][j] += sum[i - 1][j]; for(int i = 1;i <= bel[n];++i) { LL tmp = 0; for(int j = L[i];j <= n;++j) { cnt[a[j]]++; tmp = max(tmp,b[a[j]] * cnt[a[j]]); if(j == r[bel[j]]) mx[i][bel[j]] = tmp; } for(int j = L[i];j <= n;++j) cnt[a[j]]--; } LL ans = 0; while(m--) { LL ll,rr;ll = read(),rr = read(); ll = (ll ^ ans) % n + 1; rr = (rr ^ ans) % n + 1; if(ll > rr) swap(ll,rr); // printf("L is %d r is %d\n",ll,rr); if(bel[ll] == bel[rr]) { LL ma = -1; for(int j = ll;j <= rr;++j) { cnt[a[j]]++; ma = max(ma,b[a[j]] * cnt[a[j]]); } for(int j = ll;j <= rr;++j) cnt[a[j]]--; ans = ma; } else { LL ma = -1; for(int j = ll;j <= r[bel[ll]];++j) { cnt[a[j]]++; LL tmp = 0; if(bel[ll] + 1 <= bel[rr] - 1) tmp = sum[bel[rr] - 1][a[j]] - sum[bel[ll]][a[j]]; ma = max(ma,b[a[j]] * (tmp + cnt[a[j]])); } for(int j = L[bel[rr]];j <= rr;++j) { cnt[a[j]]++; LL tmp = 0; if(bel[ll] + 1 <= bel[rr] - 1) tmp = sum[bel[rr] - 1][a[j]] - sum[bel[ll]][a[j]]; ma = max(ma,b[a[j]] * (tmp + cnt[a[j]])); } for(int j = ll;j <= r[bel[ll]];++j) cnt[a[j]]--; for(int j = L[bel[rr]];j <= rr;++j) cnt[a[j]]--; if(bel[ll] + 1 <= bel[rr] - 1) ma = max(ma,mx[bel[ll] + 1][bel[rr] - 1]); ans = ma; } printf("%lld\n",ans); } system("pause"); return 0; }