zoukankan      html  css  js  c++  java
  • 洛谷T89644 palindrome回文串

    洛谷 T89643 回文串(并查集)

    洛谷:https://www.luogu.org/problem/T89643
     题目描述
     由于 Kiana 实在是太忙了,所以今天的题里面没有 Kiana。 有一个长度为 N 的字符串 S,有 K 条信息,每条信息为一个区间 [l,r],表示 S[l],S[l+1],……,S[r]是一个回文串。 出题人想知道,这个字符串中最多有多少种不同的字符。由于她 不会算,所以希望由你告诉她。
     输入格式
    输入文件包括 K+1 行。 第一行包含两个正整数 N 和 K,分别表示字符串的长度和给定信 息的数量。 接下来 K 行,每行包含两个正整数 l 和 r,表示 S[l],S[l+1],……,S[r] 是一个回文串。
    输出格式
    输出文件包括一行。 第一行包含一个正整数,表示给出的字符串中最多有多少种不同 的字符。
    分析:

    8 4

    1 5

    3 4

    7 8

    2 6
    因为1,5之间的字符串是回文的,所以1,5;2,4;对应字符相同;

    同理 3 4字符相同,所以 2 3 4 字符相同,7 8 字符相同;

    2,6: 2,6字符相同,所以2 3 4 6相同 ;3 5 相同,进一步得1 2 3 4 5 6相同
    这些一步一步合并的过程是不是很像并查集?bingo!这道题就用并查集做,以下是AC


    #include<bits/stdc++.h>
    using namespace std;
    const
    int maxn = 100005; int n, k; int f[maxn], root[maxn]; int sum; int getc(int k) {//寻找父亲并更新路径上所有节点(路径压缩) if (k == f[k])return k; else return f[k] = getc(f[k]); } void un(int x, int y) {//带秩合并,更快一些,有的题会对秩进行操作 x = getc(x), y = getc(y); if (root[x] > root[y]) f[y] = x; else { f[x] = y; if (root[x] == root[y]) root[y]++; } } int main() { freopen("shuru.txt", "r", stdin); ios::sync_with_stdio(false); cin >> n >> k; if (n < 2) { if (n == 1)cout << 1 << endl; else cout << 0 << endl; return 0; } for (int i = 1; i <= n; i++)f[i] = i; int l, r; for (int i = 1; i <= k; i++) { cin >> l >> r; for (int j = l, q = r; j < q; j++, q--) {//回文串从两端向中间,每对字符都是相同的,相同的字符加入一个并查集 un(j, q); } } for (int i = 1; i <= n; i++) { if (getc(i) == i)sum++;//有多少个字符是不同的,因为要求最大所以每个都+1
    ////可能有的点只是挂上了还没更新1->5->9   11->12 f[9]=12,但此时f[1]还未更新为12,所以要再求一次find
    } cout << sum << endl; }
  • 相关阅读:
    [HDU2866] Special Prime (数论,公式)
    [骗分大法好] 信息学竞赛 骗分导论(论文搬运)
    flayway数据库管理
    RabbitMQ的基本概念与原理
    springboot+ideal实现远程调试
    盘点总结
    mysql查看进程命令
    Java字符串正则文本替换
    springboot代码级全局敏感信息加解密和脱敏方案
    使用PMD进行代码审查
  • 原文地址:https://www.cnblogs.com/ACMerLwy/p/11250125.html
Copyright © 2011-2022 走看看