今天我挺有状态的,看过的题基本都给了正解(可能是昨晚cf div3打得跟屎一样,人品守恒,不好意思发题解了),自己也给队伍签了很多水题(不敢让队友写,怕出锅)。
最后6题滚了,有点可惜。还差B和K没做出来。
B我一眼就知道该怎么做了,推了一会发现相当可做,于是给队友嘴巴完队友写挂了 (有些小细节,比如判0什么的,下面的题解会讲)。
K有不同区间的做法一眼秒,没有的话就manacher,队友又写挂了 (弟弟们,怎么回事?
今天的训练我留意到一件事情,我跟队友讲题意的时候他们能听懂,但他们跟我讲题意的时候往往要讲好几遍。只要描述的过程中出现类似“这个”“那个”这样的代词我就完全不能接受,一定会让队友明确指出是什么东西。
以后训练我想刻意地让队友来讲题意,让他们多锻炼一下表达能力。
题目链接:http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=392
A:
要用到权值线段树的图论题,最少的情况很好想,最大的情况比较麻烦。听了金老师的solution,一如既往地没有听懂(挠头
晚点再拜读金老师的代码并更新博客。
B:
定义x,y为原始数组(样例已经给定)的值,x',y'为给定数组计算出来的值。显然可以作x-x',y-y'并提取公因式,计算一下(y-y')/(x-x')==a[i]+a[j]。到这里,解法已经很清晰了:枚举i,求j和a[j]并验证之。
细节有点恶心,要判x-x',y-y'是否为0。仔细点就可以过了。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 const int maxn = 1e5 + 10; 42 ll a[maxn], b[maxn], cnt[maxn]; 43 int t; 44 45 int main() 46 { 47 scanf("%d", &t); 48 while (t--) 49 { 50 ll n, x, y, curX = 0, curY = 0; 51 scanf("%lld%lld%lld", &n, &x, &y); 52 rep1(i, 1, n) 53 { 54 scanf("%lld", &a[i]); b[i - 1] = a[i]; 55 cnt[i - 1] = 0; 56 curX += (i * a[i]); curY += (i * a[i] * a[i]); 57 } 58 ll deltaX = x - curX, deltaY = y - curY; 59 if (!deltaX && deltaY) 60 { 61 puts("0"); 62 continue; 63 } 64 if (!deltaX && !deltaY) 65 { 66 ll ans = 0; 67 sort(b, b + n); 68 int m = unique(b, b + n) - b; 69 rep1(i, 1, n) 70 cnt[lower_bound(b, b + m, a[i]) - b]++; 71 rep0(i, 0, m) 72 ans += 1LL * cnt[i] * (cnt[i] - 1) / 2; 73 printf("%lld\n", ans); 74 continue; 75 } 76 if (abs(deltaY) % abs(deltaX)) 77 { 78 puts("0"); 79 continue; 80 } 81 ll rough = deltaY / deltaX, ans = 0; 82 for (ll i = 1; i <= n; i++) 83 { 84 ll fm = rough - 2 * a[i], fs = deltaX / fm, j = i - fs; 85 if (!fm) continue; 86 if (abs(deltaX) % abs(fm)) continue; 87 if (j <= n && j >= 1) 88 if (a[i] + a[j] == rough) ans++; 89 } 90 printf("%lld\n", ans / 2); 91 } 92 return 0; 93 }
C:
这个题给队友喂了好多假算法,都被队友hack掉了,有点迷。感觉是个姿势非常奇怪的贪心。
D:
有向图求欧拉路(貌似?我还挺想写的,但是最后的时间都在调B和K,难受
E:
sort一下,倒着判就完事了。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 const int maxn = 1e5 + 10; 42 int n, a[maxn], b[maxn], ans; 43 44 int main() 45 { 46 int t; scanf("%d", &t); 47 while (t--) 48 { 49 scanf("%d", &n); 50 rep1(i, 1, n) scanf("%d", &a[i]), b[i] = a[i]; 51 sot(b, n); 52 ans = n; 53 for (int i = n; i >= 1; i--) 54 if (a[i] == b[ans]) ans--; 55 printf("%d\n", ans); 56 } 57 return 0; 58 }
F:
没什么意思的细节签到题。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 set<char>ss = { 'a', 'e', 'i', 'y', 'o', 'u' }; 42 const int maxn = 200; 43 char s[maxn]; 44 int t; 45 46 int main() 47 { 48 scanf("%d", &t); 49 while (t--) 50 { 51 scanf("%s", s + 1); 52 int len = strlen(s + 1); 53 printf("%c", s[1]); 54 rep1(i, 2, len) 55 if (ss.count(s[i])) continue; 56 else printf("%c", s[i]); 57 puts(""); 58 } 59 return 0; 60 }
G:
温暖人心。
1 #include <bits/stdc++.h> 2 /* define */ 3 #define ll long long 4 #define dou double 5 #define pb emplace_back 6 #define mp make_pair 7 #define fir first 8 #define sec second 9 #define init(a,b) fill(begin(a),end(a),b) 10 #define sot(a,b) sort(a+1,a+1+b) 11 #define rep1(i,a,b) for(int i=a;i<=b;++i) 12 #define rep0(i,a,b) for(int i=a;i<b;++i) 13 #define repa(i,a) for(auto &i:a) 14 #define eps 1e-8 15 #define int_inf 0x3f3f3f3f 16 #define ll_inf 0x7f7f7f7f7f7f7f7f 17 #define lson curPos<<1 18 #define rson curPos<<1|1 19 /* namespace */ 20 using namespace std; 21 /* header end */ 22 23 int t, n; 24 25 int main() 26 { 27 scanf("%d", &t); 28 while (t--) 29 { 30 scanf("%d", &n); 31 for (int i = n;; i++) 32 { 33 if (i % 7 == 0 && i % 4 != 0) 34 { 35 printf("%d\n", i); 36 break; 37 } 38 } 39 } 40 return 0; 41 }
H:
水题,计算出原有极值个数p,答案显然只有p-0,p-1,p-2三种情况(样例太恶臭了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 5 using namespace std; 6 const int maxn = 2000000; 7 int A[maxn]; 8 int fg[maxn]; 9 int main() 10 { 11 int T; 12 scanf("%d",&T); 13 while(T--){ 14 int n; 15 scanf("%d",&n); 16 for(int i = 1;i <= n;i++){ 17 scanf("%d",&A[i]); 18 fg[i] = 0; 19 } 20 if(n <= 3){ 21 printf("0\n"); 22 continue; 23 } 24 int ans = 0; 25 for(int i = 2;i <= n-1;i++){ 26 if(A[i-1] < A[i] &&A[i] > A[i+1]){ 27 ans ++; 28 fg[i] = 1; 29 } 30 } 31 // for(int i = 1;i <= n;i++) 32 // printf("%d ",A[i]); 33 // printf("\n"); 34 // for(int i = 1;i <= n;i++) 35 // printf("%d ",fg[i]); 36 // printf("\n"); 37 int endflag = 0; 38 for(int i = 2;i <= n-2;i++){ 39 if(fg[i] == 1&&fg[i + 2] == 1){ 40 if(A[i] == A[i + 2]){ 41 printf("%d\n",ans-2); 42 endflag = 1; 43 break; 44 } 45 } 46 } 47 if(endflag) continue; 48 for(int i = 2;i <= n-2;i++){ 49 if(fg[i] == 1){ 50 if(A[i-1] < A[i+1]&&A[i+1] > A[i+2]){ 51 continue; 52 }else if(A[i-2] < A[i-1]&&A[i-1] > A[i+1]) { 53 continue; 54 }else{ 55 printf("%d\n",ans-1); 56 endflag = 1; 57 break; 58 } 59 } 60 } 61 if(endflag) continue; 62 printf("%d\n",ans); 63 } 64 return 0; 65 }
I:
看完题之后队友马上给结论:判读进来的数模3余几即可,虽然我没有听得很懂,不过看队友一脸坚定我还是光速敲了。奇偶性貌似是看能不能被3整除,研究一下就知道了。
1 /* basic header */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <cstdint> 9 #include <climits> 10 #include <float.h> 11 /* STL */ 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <queue> 16 #include <stack> 17 #include <algorithm> 18 #include <array> 19 #include <iterator> 20 /* define */ 21 #define ll long long 22 #define dou double 23 #define pb emplace_back 24 #define mp make_pair 25 #define fir first 26 #define sec second 27 #define init(a,b) fill(begin(a),end(a),b) 28 #define sot(a,b) sort(a+1,a+1+b) 29 #define rep1(i,a,b) for(int i=a;i<=b;++i) 30 #define rep0(i,a,b) for(int i=a;i<b;++i) 31 #define repa(i,a) for(auto &i:a) 32 #define eps 1e-8 33 #define int_inf 0x3f3f3f3f 34 #define ll_inf 0x7f7f7f7f7f7f7f7f 35 #define lson curPos<<1 36 #define rson curPos<<1|1 37 /* namespace */ 38 using namespace std; 39 /* header end */ 40 41 const int maxn = 1e4 + 10; 42 char a[maxn], b[maxn]; 43 44 int main() 45 { 46 int t; 47 scanf("%d", &t); 48 while (t--) 49 { 50 scanf("%s", a + 1); scanf("%s", b + 1); 51 int len1 = strlen(a + 1), len2 = strlen(b + 1); 52 int sum1 = 0, sum2 = 0, sign1 = 1, sign2 = 1; 53 rep1(i, 1, len1) sum1 += a[i] - '0'; 54 rep1(i, 1, len2) sum2 += b[i] - '0'; 55 if (sum1 % 3 == 2) sign1 = 2; if (sum2 % 3 == 1) sign2 = 2; 56 printf("%d\n", abs(sign1 - sign2) % 2); 57 } 58 return 0; 59 }
J:
DSU水题,队友居然写挂了要批评,还是我改对的。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2000000; 4 int pa[maxn]; 5 6 int find(int x) 7 { 8 if (pa[x] == x) return x; 9 else return pa[x] = find(pa[x]); 10 } 11 priority_queue<int, vector<int>, greater<int> > Q; 12 vector<int> G[maxn]; 13 int vis[maxn], visit[maxn]; 14 15 int main() 16 { 17 int T; 18 scanf("%d", &T); 19 while (T--) 20 { 21 int n, m; 22 scanf("%d%d", &n, &m); 23 for (int i = 1; i <= n; i++) 24 { 25 pa[i] = i; 26 vis[i] = 0; 27 visit[i] = 0; 28 G[i].clear(); 29 } 30 for (int i = 1; i <= m; i++) 31 { 32 int a, b; 33 scanf("%d%d", &a, &b); 34 if (a > b) swap(a, b); 35 G[a].push_back(b); 36 G[b].push_back(a); 37 int x = find(a); 38 int y = find(b); 39 pa[y] = x; 40 } 41 int ans = 0; 42 for (int i = 1; i <= n; i++) 43 { 44 if (find(i) == i) ans ++; 45 } 46 printf("%d\n", ans); 47 while (!Q.empty()) Q.pop(); 48 for (int i = 1; i <= n; i++) 49 { 50 if (vis[pa[i]] == 0) 51 { 52 Q.push(i); 53 vis[pa[i]] = 1; 54 visit[i] = 1; 55 } 56 } 57 int flag = 0; 58 while (!Q.empty()) 59 { 60 int x = Q.top(); 61 Q.pop(); 62 if (flag == 0) 63 { 64 printf("%d", x); 65 flag = 1; 66 } 67 else printf(" %d", x); 68 for (int i = 0; i < G[x].size(); i++) 69 { 70 if (!visit[G[x][i]]) 71 { 72 visit[G[x][i]] = 1; 73 Q.push(G[x][i]); 74 } 75 } 76 } 77 printf("\n"); 78 } 79 return 0; 80 }
K:
和队友讨论了一会口A了。如果存在不相同子串的区间,那么选定一个尽量小的“能包含所有不相同子串区间”的区间,然后往两边扩展即可。
如果不存在不相同子串的区间,直接跑manacher算回文子串个数就完事了 (天知道为什么队友会写挂这题。
L && M:
看到没有人过就溜了。