首页 > 其他分享 >NFLS 字符串题单笔记(未完结)

NFLS 字符串题单笔记(未完结)

时间:2024-11-18 21:58:20浏览次数:1  
标签:子串 未完结 int len NFLS 斑点 long 字符串 题单

POI2010 Antisymmetry

对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一样,就称作“反对称”字符串。比如00001111和010101就是反对称的,1001就不是。

现在给出一个长度为N的01字符串,求它有多少个子串是反对称的。

manacher板子,写就完了

#include <bits/stdc++.h>
#define ull long long
const int maxn = 1e7;
char SS1[maxn], S[maxn], to[500];
int n, len[maxn], tot = 1;
signed main() {
    scanf("%d%s", &n, SS1 + 1);
    S[0] = '$', S[1] = '#';
    for (register int i = 1; i <= n; ++i) S[++tot] = SS1[i], S[++tot] = '#';
    to['1'] = '0', to['0'] = '1', to['#'] = '#', to['$'] = '$';
    int pos = 1, mx = 1;
    ull ans = 0;
    for (register int i = 1; i <= tot; i += 2) {
        len[i] = (i < mx ? std::min(mx - i, len[(pos << 1) - i]) : 1);
        while (S[i + len[i]] == to[S[i - len[i]]]) len[i]++;
        if (len[i] + i > mx) {
            mx = len[i] + i;
            pos = i;
        }
        ans += len[i] >> 1;
    }
    printf("%llu\n", ans);
    return 0;
}


Bovine Genomics

FJ拥有有斑点的牛和没有斑点的牛。他刚刚完成了牛基因的一门课程,他相信牛身上的斑点是由牛的基因突变引起的。FJ花费了巨大的代价,将他的牛的基因组排序。每个基因组都是长度为的字符串。当他把牛的基因组排列起来的时候,他得到了一个像下面这样的表格(,):

位置: 1 2 3 4 5 6 7 8
斑点牛1: A A T C C C A T
斑点牛2: A C T T G C A A
斑点牛3: G G T C G C A A
普通牛1: A C T C C C A G
普通牛2: A C T C G C A T
普通牛3: A C T T C C A T
如果在某一段区间内,斑点牛和普通牛没有相同的基因段(即两组集合没有交集),那么FJ就能通过这段区间分辨两种牛。

请你帮FJ找出最短的满足条件的区间。

对每个字符串求哈希值。
\(n^2\)枚举整体的每个子串集合,然后由于求出哈希了,要判断两个字串的哈希集合是否有重复的。可以用set或者排序之后跑一遍双指针,复杂度nlogn。\(n^3 log n\)显然会T。考虑把枚举字串集合改为二分答案,二分答案的长度,然后每二分一次都check一遍。复杂度\(n^2 log_2 n\)

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int base = 29;
const int LEN = 514;
int n, m, N;
struct node {
    char str[LEN];
    ull f[LEN];
} s[LEN << 1];
ull p[LEN];
inline bool check(int st, int ed, int len) {
    set<ull> s1;
    set<ull> s2;
    for (int i = 1; i <= N; ++i) {
        if (i <= n)
            s1.insert(s[i].f[ed] - s[i].f[st - 1] * p[len]);
        else
            s2.insert(s[i].f[ed] - s[i].f[st - 1] * p[len]);
    }
    int len1 = s1.size(), len2 = s2.size(), len3;
    s1.insert(s2.begin(), s2.end());
    len3 = s1.size();
    if (len1 + len2 > len3)
        return false;
    return true;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    p[0] = 1;
    for (int i = 1; i <= 500; ++i) p[i] = (ull)(p[i - 1] * base);
    N = (n << 1);
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> s[i].str[j];
            s[i].f[j] = s[i].f[j - 1] * base + s[i].str[j] - 'A' + 1;
        }
    }
    int l = 1, r = m, mid;
    while (l < r) {
        bool flag = false;
        mid = (l + r) >> 1;
        for (int st = 1; st + mid - 1 <= m; ++st) {
            int ed = st + mid - 1;
            if (check(st, ed, mid)) {
                flag = true;
                break;
            }
        }
        if (flag)
            r = mid;
        else
            l = mid + 1;
    }
    printf("%d", l);
    return 0;
}

反例 贴一下卢的厌氧代码,不开O0过不去

#include <iostream>
#include <algorithm>
#pragma GCC optimize("O0")
using namespace std;
typedef long long ll;
const int N = 1010;
const ll ba = 131, p = 1e9 + 7;

int n, m;
ll h[N], ha[N][N], hb[N][N];
ll A[N], B[N];
char a[N][N], b[N][N];

bool check(int l, int r) {
    for (int i = 1; i <= n; ++i) A[i] = (p + ha[i][r] - (ha[i][l - 1] * h[r - l + 1])) % p;
    for (int i = 1; i <= n; ++i) B[i] = (p + hb[i][r] - (hb[i][l - 1] * h[r - l + 1])) % p;
    sort(A + 1, A + n + 1), sort(B + 1, B + n + 1);
    int len = 1;
    bool flag = 1;
    for (int i = 1; i <= n; ++i) {
        while (A[i] > B[len]) ++len;
        if (A[i] == B[len]) {
            flag = 0;
            break;
        }
    }
    return flag;
}

int main() {
    cin >> n >> m;
    h[0] = 1;
    for (int i = 1; i <= m; ++i) h[i] = h[i - 1] * ba % p;
    for (int i = 1; i <= n; ++i) {
        cin >> (a[i] + 1);
        for (int j = 1; j <= m; ++j) ha[i][j] = (ha[i][j - 1] * ba + (a[i][j] - 'A')) % p;
    }
    for (int i = 1; i <= n; ++i) {
        cin >> (b[i] + 1);
        for (int j = 1; j <= m; ++j) hb[i][j] = (hb[i][j - 1] * ba + (b[i][j] - 'A')) % p;
    }
    int l = 1, r = m, mid;
    bool flag = 0;
    while (l < r) {
        mid = (l + r) >> 1;
        flag = 0;
        for (int i = 1; i + mid - 1 <= m; ++i)
            if (check(i, i + mid - 1)) {
                flag = 1;
                break;
            }
        if (flag)
            r = mid;
        else
            l = mid + 1;
    }
    cout << l << endl;
    return 0;
}

friends

有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将其复制一遍得到T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在你得到了U,请你找出S.

求出哈希。
枚举插入字符的点,判断前面s和后面的s是否一样。
技巧:字符串\(S _{1...n}\) 现在有\(hash1_{1...a}, hash2_{a+2...n}\)
那么\(hash1,hash2\)拼一起的哈希值就是$hash1 * base^{hash2.length()+1} + hash2 $

似乎在梦中见过的样子

一个长度为 n 的字符串,所有形似于 A+B+A 的子串都是它的替身 , 且len(A)>=k,len(B)>=1 (位置不同其他性质相同的子串算不同子串,位置相同但拆分不同的子串算同一子串),求它的替身的数量.

枚举A串,kmp,n^2复杂度。来不及写了,先走了

标签:子串,未完结,int,len,NFLS,斑点,long,字符串,题单
From: https://www.cnblogs.com/Kang-shifu/p/18553765

相关文章

  • NFLS DP题单笔记(做不动了未完结)
    录制唱片你刚刚继承了流行的“破锣摇滚”乐队录制的尚未发表的\(N\)(\(1\leqN\leq20\))首歌的版权。你打算从中精选一些歌曲,发行\(M\)(\(1\leqM\leq20\))张CD。每一张CD最多可以容纳\(T\)(\(1\leqT\leq20\))分钟的音乐,一首歌不能分装在两张CD中。CD数量可以用完,也可以......
  • NFLS 图论题单笔记(完结)
    John的农场是一张N*N的方格图,贝茜住在左上角(1,1),John住在右下角(N,N)。现在贝茜要去拜访John,每次都只能往四周与之相邻的方格走,并且每走一步消耗时间T。同时贝茜每走三步就要停下来在当前方格吃草,在每个方格吃草的用时是固定的,为H[i][j]。John想知道贝茜最少要多久才能到达Joh......
  • 洛谷题单指南-二叉堆与树状数组-P1908 逆序对
    原题链接:https://www.luogu.com.cn/problem/P1908题意解读:求逆序对,前面介绍过归并排序的做法,参考:https://www.cnblogs.com/jcwy/p/184077,这里介绍树状数组的做法。解题思路:设数组a[n]里的整数只包括1~n,显然对于此题,可以通过离散化得到这样的数组。要计算逆序对,就是要计算对于......
  • 小寄巧——给洛谷题单快速生成一份目录
    以此题单为例,首先我们在浏览器中打开,F12切换到Console,输入document.querySelectorAll(".titlea"),然后复制返回的所有内容,粘贴到VSCode里,内容大致如下:NodeList(15)[a.title.color-default,a.title.color-default,a.title.color-default,a.title.color-default,a.title......
  • 洛谷题单指南-二叉堆与树状数组-P3368 【模板】树状数组 2
    原题链接:https://www.luogu.com.cn/problem/P3368题意解读:树状数组应用-区间修改,单点求值解题思路:设原数组为s[N],其差分数组为a[N]操作一:区间修改要对s[x]~s[y]每个数增加k,相当于对a[x]加k,对a[y+1]减k,O(n)的操作变成了O(1)的操作,利用树状数组tr[N]的add(x,k),add(y+......
  • 洛谷题单指南-二叉堆与树状数组-P3374 【模板】树状数组 1
    原题链接:https://www.luogu.com.cn/problem/P3374题意解读:树状数组模版:单点修改,区间求值。解题思路:树状数组-BinaryIndexTree可以动态维护一组数,可以O(logn)的修改一个数,也可以O(logn)的计算一段区间的和。思考一下朴素做法:如何修改一个数,计算区间和?如果是常规数组,修改操作......
  • 【未完结】 AtCoder Beginner Contest 380 题解
    AtCoderBeginnerContest380Rated:\(770\)A-123233简单模拟B-HurdleParsing字符串模拟C-MoveSegment找到第\(k\)个块的下标,模拟。D-StrangeMirroringE-1DBucketToolF-ExchangeGameG-AnotherShuffleWindow......
  • 动态规划题单2
    第一个题单编辑到后面实在是太卡了,就新开了一个,以后应该也会\(30\)题为一个题单。31.CF1580D SubsequenceCF1580D Subsequence不会笛卡尔树,但是看到题解区的妙妙解法......题目的式子非常大便,我们考虑把它翻译成人话:一个子序列的价值为:\(sum*m-每两个数及他们之间的所......
  • 动态规划题单1
    可恶的动态规划,每次考试基本都写不出来,于是特意整理个动态规划提单1.CF1620F BipartiteArrayCF1620F BipartiteArray题意等价于:要把这些点分成两部分,每一部分之间都没有边相连,等价于把这个序列中分成两个上升子序列。在DP时肯定要记录两个序列的末尾,但发现其中一个序列的......
  • 2024.11.13 DP题单
    录制唱片你刚刚继承了流行的“破锣摇滚”乐队录制的尚未发表的\(N\)(\(1\leqN\leq20\))首歌的版权。你打算从中精选一些歌曲,发行\(M\)(\(1\leqM\leq20\))张CD。每一张CD最多可以容纳\(T\)(\(1\leqT\leq20\))分钟的音乐,一首歌不能分装在两张CD中。CD数量可以用完,也可以......