并查集

来源:互联网 发布:走台步的基本技巧 知乎 编辑:程序博客网 时间:2024/06/06 09:55

Palindrome

A string is palindrome if it can be read the same way in either direction, for example “maram” is
palindrome, while “ammar” is not.
You are given a string of n characters, where each character is either a lowercase English letter or
a question mark (?). You are also given a set of m constraints. Your task is to count the number of
ways in which we can replace all question marks with lowercase English letters such that the
resulting string is a palindrome that does not violate the given constraints.
The constraints are in the form of pairs of indices of letters that should be the same.

Input

The first line of input contains one integer T, the number of test cases (1 ≤ T ≤ 256).
Each test case begins with two integers: n representing the string size (1 ≤ n ≤ 50000) and m
representing the number of constraints (0 ≤ m ≤ 10000).
The next line contains a string of length n. The next m lines, each contains two integers x and y (1
<= x < y <= n), where letters at index x and index y must be the same.
Test cases are separated by a blank line.

Output

For each test case, print the number of ways modulo 1,000,000,007 (109
+ 7).

Sample Input
45 1ma??m1 55 4ma??m1 21 51 33 47 0acm?cpc4 1????1 4
Sample Output
2600676

这题用并查集过了,没想到啊

#include<cstdio>#include<vector>using namespace std;const int N = 1e5 + 50;const long long mod = 1e9 + 7;char s[N];vector<int>e[N];int n, m,fa[N];int find_fa(int x){    if (x == fa[x]) return x;    fa[x] = find_fa(fa[x]);    return find_fa(fa[x]);}int main(){    int t;    scanf("%d",&t);    while (t--) {        scanf("%d%d",&n,&m);        scanf("%s",s+1);        for (int i = 0; i <= n; i++) e[i].clear();        for (int i = 1; i <= m; i++) {            int a, b;            scanf("%d%d",&a,&b);            e[a].push_back(b);        }        for (int i = 1; i <= n; i++) {            e[i].push_back(n - i + 1);        }        for (int i = 0; i <= n; i++) fa[i] = i;        bool flag = 1;        for (int i = 1; i <= n; i++) {            for (int j = 0; j < e[i].size(); j++) {                int v = e[i][j];                int f1 = find_fa(i);                int f2 = find_fa(v);                if (f1 != f2) {                    if (s[f1] != '?'&&s[f2] != '?'&&s[f1] != s[f2]) {                        flag = 0; break;                    }                    else if (s[f1] != '?'&&s[f2] == '?') s[f2] = s[f1];                    fa[f1] = f2;                }            }        }        int cnt = 0;        for (int i = 1; i <= n; i++) {            if (fa[i] == i&&s[i] == '?') cnt++;        }        if (flag == 0) printf("0\n");        else {            long long ans = 1;            for (int i = 1 ;i <= cnt; i++)                ans = ans * 26 % mod;            printf("%I64d\n",ans);        }    }    return 0;}

以后再更

原创粉丝点击