The 16th Zhejiang provincial collegiate programming contest

今天我挺有状态的,看过的题基本都给了正解(可能是昨晚cf div3打得跟屎一样,人品守恒,不好意思发题解了),自己也给队伍签了很多水题(不敢让队友写,怕出锅)。

最后6题滚了,有点可惜。还差B和K没做出来。

B我一眼就知道该怎么做了,推了一会发现相当可做,于是给队友嘴巴完队友写挂了 (有些小细节,比如判0什么的,下面的题解会讲)。

K有不同区间的做法一眼秒,没有的话就manacher,队友又写挂了 (弟弟们,怎么回事?

今天的训练我留意到一件事情,我跟队友讲题意的时候他们能听懂,但他们跟我讲题意的时候往往要讲好几遍。只要描述的过程中出现类似“这个”“那个”这样的代词我就完全不能接受,一定会让队友明确指出是什么东西。

以后训练我想刻意地让队友来讲题意,让他们多锻炼一下表达能力。

题目链接:http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=392


A:

图论题。DSU+权值线段树+二分查询+读优才能过。考验码力。

  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 sot(a,b) sort(a+1,a+1+b)
 28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
 29 #define rep0(i,a,b) for(int i=a;i<b;++i)
 30 #define repa(i,a) for(auto &i:a)
 31 #define eps 1e-8
 32 #define int_inf 0x3f3f3f3f
 33 #define ll_inf 0x7f7f7f7f7f7f7f7f
 34 #define lson curPos<<1
 35 #define rson curPos<<1|1
 36 /* namespace */
 37 using namespace std;
 38 /* header end */
 39 
 40 const int maxn = 1e5 + 10;
 41 ll sum[maxn << 2], sumn[maxn << 2], sume[maxn << 2], nei[maxn << 2], summan[maxn << 2];
 42 int f[maxn], fsz[maxn], n, Q;
 43 ll fed[maxn], sn, sm, tn;
 44 
 45 inline ll read()
 46 {
 47     ll d = 0;
 48     char s = getchar();
 49     while (s < '0' || s > '9')
 50         s = getchar();
 51     while (s >= '0' && s <= '9')
 52     {
 53         d = d * 10 + s - '0';
 54         s = getchar();
 55     }
 56     return d;
 57 }
 58 
 59 int findFa(int x)
 60 {
 61     if (f[x] == x) return x;
 62     return f[x] = findFa(f[x]);
 63 }
 64 
 65 void maintain(int curPos)
 66 {
 67     sum[curPos] = sum[lson] + sum[rson];
 68     sumn[curPos] = sumn[lson] + sumn[rson];
 69     sume[curPos] = sume[lson] + sume[rson];
 70     nei[curPos] = nei[lson] + nei[rson];
 71     summan[curPos] = summan[lson] + summan[rson];
 72 }
 73 
 74 void build(int curPos, int curL, int curR)
 75 {
 76     if (curL == curR)
 77     {
 78         sumn[curPos] = sum[curPos] = curL == 1 ? n : 0;
 79         sume[curPos] = nei[curPos] = summan[curPos] = 0;
 80         return;
 81     }
 82     int mid = (curL + curR) >> 1;
 83     build(lson, curL, mid); build(rson, mid + 1, curR);
 84     maintain(curPos);
 85 }
 86 
 87 void add(int pos, int val, int curPos, int curL, int curR, ll ve)
 88 {
 89     if (curL == curR)
 90     {
 91         sum[curPos] += (ll)curL * val;
 92         sumn[curPos] += val;
 93         sume[curPos] += ve;
 94         nei[curPos] = (ll)curL * (curL - 1) / 2 * sumn[curPos] - sume[curPos];
 95         summan[curPos] = (ll)curL * (curL - 1) / 2 * sumn[curPos];
 96         return;
 97     }
 98     int mid = (curL + curR) >> 1;
 99     if (pos <= mid)
100         add(pos, val, lson, curL, mid, ve);
101     else
102         add(pos, val, rson, mid + 1, curR, ve);
103     maintain(curPos);
104 }
105 
106 void query(int curPos, int l, int r, ll K)
107 {
108     if (l == r)
109     {
110         int _l = 1, _r = sumn[curPos], ans = K ? 1 : 0;
111         while (_l <= _r)
112         {
113             int mid = (_l + _r) >> 1;
114             ll sp = sn + (ll) l * mid;
115             ll g = sp * (sp - 1) / 2 - sm - (ll) l * (l - 1) / 2 * mid;
116             // cerr << mid << ' ' << g << '\n';
117             if (g <= K)
118             {
119                 if (g < K)
120                     ans = max(ans, mid + 1);
121                 else
122                     ans = max(ans, mid);
123                 _l = mid + 1;
124             }
125             else
126                 _r = mid - 1;
127         }
128         tn += ans;
129         return;
130     }
131     int mid = (l + r) >> 1;
132     ll sp = sn + sum[rson];
133     ll g = sp * (sp - 1) / 2 - summan[rson] - sm;
134     if (g == K)
135     {
136         sn += sum[rson];
137         tn += sumn[rson];
138     }
139     if (g < K)
140     {
141         sn += sum[rson];
142         sm += summan[rson];
143         tn += sumn[rson];
144         query(lson, l, mid, K);
145     }
146     if (g > K)
147         query(rson, mid + 1, r, K);
148 }
149 
150 int main()
151 {
152     int t=read();
153     while (t--)
154     {
155         n=read(),Q=read();
156         rep1(i, 1, n)
157         {
158             f[i] = i, fsz[i] = 1, fed[i] = 0;
159         }
160         build(1, 1, n);
161         int bsz = n;
162         while (Q--)
163         {
164             int op=read();
165             if (op == 1)
166             {
167                 int x=read(), y=read(); 
168                 int dx = findFa(x), dy = findFa(y);
169                 if (dx == dy)
170                 {
171                     fed[dx]++;
172                     add(fsz[dx], 0, 1, 1, n, 1);
173                 }
174                 else
175                 {
176                     add(fsz[dx], -1, 1, 1, n, -fed[dx]);
177                     add(fsz[dy], -1, 1, 1, n, -fed[dy]);
178                     add(fsz[dx] + fsz[dy], 1, 1, 1, n, fed[dx] + fed[dy] + 1);
179                     f[dx] = dy;
180                     fsz[dy] += fsz[dx];
181                     fed[dy] += fed[dx] + 1;
182                     bsz--;
183                 }
184             }
185             else
186             {
187                 ll K=read();
188                 int mi = max(bsz - K, 1LL), ma;
189                 K -= nei[1];
190                 if (K <= 0)
191                     ma = bsz;
192                 else
193                 {
194                     sn = sm = tn = 0;
195                     query(1, 1, n, K);
196                     ma = bsz - tn + 1;
197                 }
198                 printf("%d %d\n", mi, ma);
199             }
200         }
201     }
202     return 0;
203 }
View Code

不上读优就是这样的下场(1920ms那次A得莫名其妙):

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。仔细点就可以过了。

/* basic header */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdint>
#include <climits>
#include <float.h>
/* STL */
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <array>
#include <iterator>
/* define */
#define ll long long
#define dou double
#define pb emplace_back
#define mp make_pair
#define fir first
#define sec second
#define init(a,b) fill(begin(a),end(a),b)
#define sot(a,b) sort(a+1,a+1+b)
#define rep1(i,a,b) for(int i=a;i<=b;++i)
#define rep0(i,a,b) for(int i=a;i<b;++i)
#define repa(i,a) for(auto &i:a)
#define eps 1e-8
#define int_inf 0x3f3f3f3f
#define ll_inf 0x7f7f7f7f7f7f7f7f
#define lson curPos<<1
#define rson curPos<<1|1
/* namespace */
using namespace std;
/* header end */

const int maxn = 1e5 + 10;
ll a[maxn], b[maxn], cnt[maxn];
int t;

int main()
{
    scanf("%d", &t);
    while (t--)
    {
        ll n, x, y, curX = 0, curY = 0;
        scanf("%lld%lld%lld", &n, &x, &y);
        rep1(i, 1, n)
        {
            scanf("%lld", &a[i]); b[i - 1] = a[i];
            cnt[i - 1] = 0;
            curX += (i * a[i]); curY += (i * a[i] * a[i]);
        }
        ll deltaX = x - curX, deltaY = y - curY;
        if (!deltaX && deltaY) //除0说明无解
        {
            puts("0");
            continue;
        }
        if (!deltaX && !deltaY) //这情况就很有意思了
        {
            ll ans = 0;
            sort(b, b + n);
            int m = unique(b, b + n) - b;
            rep1(i, 1, n)
            cnt[lower_bound(b, b + m, a[i]) - b]++;
            rep0(i, 0, m)
            ans += 1LL * cnt[i] * (cnt[i] - 1) / 2;
            printf("%lld\n", ans);
            continue;
        }
        //不能整除说明无解,不能跟上面的if合在一起,不然会报浮点错误
        if (abs(deltaY) % abs(deltaX))
        {
            puts("0");
            continue;
        }
        //有解,枚举i即可
        ll rough = deltaY / deltaX, ans = 0;
        for (ll i = 1; i <= n; i++)
        {
            ll fm = rough - 2 * a[i], fs = deltaX / fm, j = i - fs;
            if (!fm) continue;
            if (abs(deltaX) % abs(fm)) continue;
            if (j <= n && j >= 1)
                if (a[i] + a[j] == rough) ans++;
        }
        printf("%lld\n", ans / 2);
    }
    return 0;
}
View Code

C:

这个题给队友喂了好多假算法,都被队友hack掉了,有点迷。当时感觉是个姿势非常奇怪的贪心。

晚上写完这个博客之后洗了个澡,突然明白这题是从前往后贪心,线段树维护。(当时看到n<=1e5我就觉得是Onlogn的算法)

然而过了两天之后我发现了更好的做法,发现这个题只要维护得好,On就可以做了。

不得不承认确实是个出得不错的贪心,看完代码甚至觉得这题非常傻……

 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 sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf 0x3f3f3f3f
33 #define ll_inf 0x7f7f7f7f7f7f7f7f
34 #define lson curPos<<1
35 #define rson curPos<<1|1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 1e5 + 10;
41 int n, a[maxn], cnt[maxn], cntTwi[maxn], ans[maxn]; //cntTwi[i]==cnt[i]*2
42 set<pair<int, int>>s; //次数的两倍和数值makepair,set的特性会先按cnt排序,再按数值排序
43 set<int>all;
44 
45 void init(int n)
46 {
47     s.clear(); all.clear();
48     rep1(i, 1, n) cnt[i] = cntTwi[i] = ans[i] = 0;
49 }
50 
51 int main()
52 {
53     int t; scanf("%d", &t);
54     while (t--)
55     {
56         scanf("%d", &n);
57         init(n);
58         for (int i = 1; i <= n; i++)
59         {
60             scanf("%d", &a[i]);
61             cnt[a[i]]++;
62         }
63         for (int i = 1; i <= n; i++)
64             if (cnt[i])
65             {
66                 all.insert(i);
67                 s.emplace(cntTwi[i] = 2 * cnt[i], i);
68             }
69         int flag = 0; //无解标志
70         for (int i = 1; !flag && i <= n; i++)
71         {
72             int p = s.rbegin()->second; //先处理cnt最多而且数值较大的那个数字
73             if (cntTwi[p] > n - i + 1) //如果cnt大于剩余位置的一半,必然无解
74             {
75                 flag = 1;
76                 puts("Impossible");
77                 break;
78             }
79             else if (cntTwi[p] < n - i + 1 || p == a[i]) //如果要处理的数字正好for到了,不能放下去,那就找个最小的可用的数字替代之
80             {
81                 auto it = all.begin();
82                 if (*it == a[i]) it++;
83                 p = *it;
84             }
85             //更新re
86             s.erase({cntTwi[a[i]], a[i]});
87             s.erase({cntTwi[p], p});
88             if (--cntTwi[a[i]]) s.emplace(cntTwi[a[i]], a[i]);
89             if (--cntTwi[p]) s.emplace(cntTwi[p], p);
90             if (--cnt[ans[i] = p] == 0) all.erase(p);
91         }
92         if (!flag)
93             for (int i = 1; i <= n; i++)
94                 printf("%d%c", ans[i], i < n ? ' ' : '\n');
95     }
96     return 0;
97 }
View Code

D:

有向图求欧拉路(貌似?我还挺想写的,但是最后的时间都在调B和K,难受。

补题的时候发现这题并没有我想得这么简单,幸好比赛的时候没写,不然更浪费时间了。

原本我还想着什么记忆化之类的事情,dalao直接一发暴力就A了。

Input最后有一句“It's guaranteed that the sum of  of all test cases will not exceed 10^6”。当时没看到……

 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 sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf 0x3f3f3f3f
33 #define ll_inf 0x7f7f7f7f7f7f7f7f
34 #define lson curPos<<1
35 #define rson curPos<<1|1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 struct Graph
41 {
42     struct Vertex
43     {
44         vector<int>to;
45         int inDeg, vis; //inDeg:入度
46     };
47     vector<Vertex>vertex;
48     vector<int>eulerPath;
49     Graph(int n): vertex(n) {}
50 
51     int dfs(int u, int dep)
52     {
53         vertex[u].vis = 1;
54         eulerPath.pb(u);
55         if (!dep) return 1;
56         for (auto to : vertex[u].to)
57             if (!vertex[to].vis)
58             {
59                 int flag = 1;
60                 vertex[to].inDeg++;
61                 for (auto to : vertex[u].to)
62                     if (!--vertex[to].inDeg && !vertex[to].vis) flag = 0;
63                 if (flag && dfs(to, dep - 1))
64                     return 1;
65                 vertex[to].inDeg--;
66                 for (auto to : vertex[u].to) vertex[to].inDeg++;
67             }
68         //如果for一遍都没结果,说明不存在欧拉路
69         eulerPath.pop_back();
70         vertex[u].vis = 0;
71         return 0;
72     }
73 };
74 
75 int main()
76 {
77     int t; scanf("%d", &t);
78     while (t--)
79     {
80         int n; scanf("%d", &n);
81         Graph g(n + 1);
82         for (int i = 1; i <= n; i++) //建图
83             for (auto to :
84                     {
85                         i / 2, i - 1, i * 2, i * 2 + 1
86                     })
87                 if (2 <= to && to <= n)
88                     g.vertex[i].to.pb(to), g.vertex[to].inDeg++;
89         if (!g.dfs(1, n - 1))
90             puts("Impossible");
91         else
92             for (int i = 0; i < g.eulerPath.size(); i++)
93                 printf("%d%c", g.eulerPath[i], i < g.eulerPath.size() - 1 ? ' ' : '\n');
94     }
95     return 0;
96 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

K:

和队友讨论了一会口A了。如果存在不相同子串的区间,那么选定一个尽量小的“能包含所有不相同子串区间”的区间,然后往两边扩展即可。

如果不存在不相同子串的区间,直接跑manacher算回文子串个数就完事了。 (赛后队友原来是死在ans没开LL,队友锅++

 1 #include <cstdio>
 2 #include <string>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 
 8 const int maxn = 2e6+1;
 9 
10 char ma[maxn * 2];
11 int mp[maxn * 2];
12 
13 long long int manacher (string s) {
14     auto len = s.length();
15     int l = 0;
16     ma[l++] = '$';
17     ma[l++] = '#';
18     for (int i = 0; i < len; i++) {
19         ma[l++] = s[i];
20         ma[l++] = '#';
21     }
22     ma[l] = 0;
23     int mx = 0, id = 0;
24     for (int i = 0; i < l; i++) {
25         mp[i] = mx > i ? min(mp[2*id-i], mx-i) : 1;
26         while (ma[i + mp[i]] == ma[i-mp[i]]) mp[i]++;
27         if (i + mp[i] > mx) {
28             mx = i + mp[i];
29             id = i;
30         }
31     }
32     long long ans = 0;
33     for (int i = 0; i < 2 * len + 2; i++) {
34         ans += mp[i] / 2;
35     }
36     return ans;
37 }
38 
39 int main(void) {
40     ios::sync_with_stdio(false);
41     int T;
42     cin >> T;
43     while (T--) {
44         string s, t;
45         cin >> s >> t;
46         bool flag = true;
47         int left = -1, right = -1;
48         for (auto i = 0; i < s.length(); i++) {
49             if (s[i] != t[i]) {
50                 if (flag) {
51                     left = i;
52                     flag = false;
53                 }
54                 right = i;
55             }
56         }
57         if (right == -1) {
58             cout << manacher(s) << endl;
59         } else {
60             bool possible = true;
61             for (int i = 0; i <= right - left; i++) {
62                 if (s[left + i] != t[right - i]) {
63                     possible = false;
64                 }
65             }
66             long long ans = 0;
67             if (possible) {
68                 ans = 1;
69                 while (--left >= 0 && ++right < s.length()) {
70                     if (s[left] == s[right] && t[left] == t[right] && s[left] == t[left]) {
71                         ans++;
72                     } else {
73                         break;
74                     }
75                 }
76             }
77             // with different bytes
78             cout << ans << endl;
79         }
80     }
81     return 0;
82 }
View Code

L && M:

看到没有人过就溜了。

转载于:https://www.cnblogs.com/JHSeng/p/10780537.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值