题解 P4795【基因工程】

· · 题解

P4795 基因工程

P4795 [BalticOI 2018]基因工程

我们知道有朴素的 O(n^3) 的暴力,我又不会正解,于是我们来乱搞

思路

既然复杂度不会优化,那就优化常数。

朴素字符串匹配是 O(n) 的,于是我们用一个 4\times 4100\texttt{bitset} 维护每个字符串,其中 4 代表的是字符集大小,4100 代表的是字符串长度,第 i,j 个数为 1 的意义是第 j 位的字符为第 i 种字符。

但是这样还是会 \texttt{TLE 91pts/94pts}

于是我们考虑随机打乱字符串,使其期望运行次数减小。

我们使用 random_shuffle 随机打乱字符串顺序。

然后就过了...

时间复杂度 O(\dfrac {n^3}{w})

如果你过不了,那么你需要一些评测机波动和玄学

```cpp #include<bits/stdc++.h> using namespace std; #define ll long long int n,m,k; struct node{ char a[4105]; int id; }a[4105]; bitset<4105>b[4110][5]; inline int change(char ch){ switch(ch){ case 'A': return 1; case 'T': return 2; case 'G': return 3; case 'C': return 4; } } inline void read(char *a){ char ch=getchar(); while(ch<'A'||ch>'Z') ch=getchar(); int len=0; while(ch>='A'&&ch<='Z') a[++len]=ch,ch=getchar(); } int main(){ scanf("%d %d %d",&n,&m,&k); for(int i=1;i<=n;i++){ read(a[i].a); a[i].id=i; } random_shuffle(a+1,a+n+1); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ b[i][change(a[i].a[j])].set(j); } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i!=j){ int s=0; for(int p=1;p<=4;p++){ s+=(b[i][p]&b[j][p]).count(); } if(s+k!=m) goto nxt; } } printf("%d",a[i].id); return 0; nxt:; } return 0; } ``` 再见 $qwq$~