CF1109

CF1109

Codeforces Round 539 (Div. 1)

CF1109A

link

CF1109A题意

给定一个含 \(n\) 个整数的序列 \(a\),定义 \((l,r)\) 是一个funny pair当且仅当 \(r>l,r-l+1\) 为偶数,且 \(a\) 中下标自 \(l\)\(\frac{l+r-1}2\) 的数的异或和等于下标自 \(\frac{l+r-1}2+1\)\(r\) 的数的异或和。求序列 \(a\)funny pairs的个数。

CF1109A题解

首先想到前缀和,然后 \(s_l\oplus s_{mid}=s_{mid}\oplus s_r\),然后发现 \(s_l=s_r\)
然后就没了。

CF1109A代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
    int x = 0, f=  1;char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}
    return x * f;
}
map<int,int> mp1,mp2;
int n;
signed main(){
    n = read();int sum = 0,ans = 0;
    mp2[0]++;
    for(int i = 1;i <= n;i++){
        sum ^= read();
        if(i & 1){ans += mp1[sum];mp1[sum]++;}
        else {ans += mp2[sum];mp2[sum]++;}
    }
    printf("%lld\n",ans);
    return 0;
}

CF1109B

link

CF1109B题意

给定一个回文字符串,如今想将这个字符串用 \(k\) 刀切成 \(k+1\) 个部分,然后对这 \(k+1\) 个子串重新排列(不能改变子串内部的字符顺序)使得得到的新串也为回文串且不与原串一样。求出这个最小的数 \(k\)。如果做不到,则输出Impossible

CF1109B题解

猜想答案只有 \(1,2\)Impossible三种情况。
尝试证明:

首先,无解的情况当且仅当所有的字符(如果是奇数长度忽略中间的那个)相同。证明显然。
然后考虑剩下的情况。
先考虑长度为奇数的情况:
发现,如果 \([1,\lfloor\frac{n}{2}\rfloor]\) 不是回文串,那么直接在 \(\lfloor\frac{n}{2}\rfloor,\lfloor\frac{n}{2}\rfloor+1\) 各切一刀即可。
否则,结构一定满足 ABACABA 这种情况,直接像 AB|ACA|BA 这么切即可。不必担心 B 是空串,我们刚刚已经判过无解的情况了。
那么只要长度是奇数,那么答案就是 \(2\)
然后再考虑长度是偶数的情况。
发现,如果将原串分成两部分,进行分讨:
左半边串不是回文串,显然只需要操作一次,然后交换即可,答案就是 \(1\)
左半边串是回文串。那么先算一下左半边串的答案,发现,如果左半边串答案是 \(1\),那么结构就会形如 ABAB,这个时候显然在中间切一下即可。
如果左半边串答案是 \(2\),那么结构就会形如 ACAACA,直接像 AC|AA|CA 切开即可。

CF1109B代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5000 + 10;
int chk(char *ch,int n){
    if(n & 1){return 2;}
    for(int i = 1;i <= n / 2;i++){
        if(ch[i] != ch[n / 2 - i + 1])return 1;
    }
    return chk(ch,n / 2);
}
char ch[maxn];
int n;
signed main(){
    scanf("%s",ch + 1);n = strlen(ch + 1);
    bool flag = true;
    for(int i = 2;i <= n;i++){
        if(i == n / 2 + 1 && (n & 1))continue;
        if(ch[i] != ch[1]){flag = false;break;}
    }
    if(flag){puts("Impossible");return 0;}
    printf("%d\n",chk(ch,n));
    return 0;
}
posted @ 2023-12-28 08:04  Call_me_Eric  阅读(26)  评论(0)    收藏  举报
Live2D