zoukankan      html  css  js  c++  java
  • 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 << '
    ';
    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
    ", 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
    ", 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
    ", 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 ? ' ' : '
    ');
    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 ? ' ' : '
    ');
    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
    ", 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
    ", 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
    ");
    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("
    ");
    34         // for(int i = 1;i <= n;i++)
    35         //     printf("%d ",fg[i]);
    36         // printf("
    ");
    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
    ",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
    ",ans-1);
    56                     endflag = 1;
    57                     break;
    58                 }
    59             }
    60         }
    61         if(endflag) continue;
    62         printf("%d
    ",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
    ", 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
    ", 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("
    ");
    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:

    看到没有人过就溜了。

  • 相关阅读:
    hdu 1164 Eddy's research I
    hdu 3794 Magic Coupon
    hdu 1460 完数
    hdu 1201 18岁生日
    求一组整数中所有素数之和
    备忘录
    c判断括弧是否匹配
    N!大整数阶乘问题
    计算一个人从出生到现在活了多少天
    java web.xml配置详解(转)
  • 原文地址:https://www.cnblogs.com/JHSeng/p/10780537.html
Copyright © 2011-2022 走看看