zoukankan      html  css  js  c++  java
  • [Test1.11]-T1匹配 Matching

    Description:

    给定两个含小写字母、通配符的字符串 (S), (T)
    出于简化问题的考虑,这里的通配符只有"(?)"一种。它可以匹配任意一个字符。
    一个串 (T)(S)({pos}) 位置上出现,当且仅当:
    ∀1 ≤ i ≤ |T|, Spos+i 1 = Ti | Spos+i 1 =′?′ | Ti =′?′
    你的任务是:求 T 在 S 中的出现次数。

    数据范围:

    |T| ≤ |S| ≤ 2 × 1e5
    时限:3s
    空间:128mb

    Solution:

    solution

    代码:

    #include<iostream>
    #include<cstdio>
    #include<complex>
    #include<cstring>
    #define R register
    #define ll long long
    #define eps 1e-8
    #define is0(x) ((x) < eps && -(x) < eps)
    using namespace std;
    namespace IO
    {
    	template<class T>
    	void rea(T &x)
    	{
    		char ch=getchar();long long f(0);x = 0;
    		while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
    		while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    		x = f?-x:x;
    	}
    	template<class T>
    	T max(T a, T b){return (a>b?a:b);}
    	template<class T>
    	T min(T a, T b){return (a<b?a:b);}
    }
    const long long N = 600005;
    char s[N], t[N], pre[N];
    long long pos[N], tot, lens, lent, ans[N];
    complex<double>a[N], b[N], x[N], y[N];
    void init(long long k)
    {
    	long long len = 1<<k;
    	for(R long long i = 0; i < len; ++i)
    		pos[i] = (pos[i>>1]>>1)|((i&1)<<(k-1));
    }
    void fft(complex<double> *a, long long n, long long flag)
    {
    	for(R long long i = 0; i < n; ++i) if(i < pos[i]) swap(a[i], a[pos[i]]);
    	for(R long long len = 1; len < n; len *= 2)
    	{
    		complex<double> wx = complex<double>(cos(M_PI/len), flag*sin(M_PI/len));
    		for(R long long i = 0; i < n; i += len*2)
    		{
    			complex<double> w(1, 0);
    			for(R long long j = i; j < i+len; ++j)
    			{
    				complex<double> x = a[j];
    				complex<double> y = w*a[j+len];
    				a[j] = x+y;
    				a[j+len] = x-y;
    				w *= wx;
    			}
    		}
    	}
    	if(flag == -1) for(R long long i = 0; i < n; ++i) a[i] /= n;
    }
    void solve(long long flag, long long n)
    {
    	fft(x, n, 1);fft(y, n, 1);
    	for(R long long i = 0; i < n; ++i) x[i] *= y[i];
    	fft(x, n, -1);
    	for(R long long i = 0; i < n; ++i) ans[i] += (long long)(x[i].real()+0.5)*flag;
    }
    int main()
    {
    	freopen("matching.in","r",stdin);
    	freopen("matching.out","w",stdout);
    	scanf("%s%s", s, pre);
    	lens = strlen(s), lent = strlen(pre);
    	for(R long long i = 0; i < lent; ++i) t[i] = pre[lent-i-1];
    	for(R long long i = 0; i < lens; ++i) a[i] = (double)((s[i]=='?'?0 : s[i]-'a'+1));
    	for(R long long i = 0; i < lent; ++i) b[i] = (double)((t[i]=='?'?0 : t[i]-'a'+1));
    	long long P = 1, k = 0;
    	while(P <= lens+lent) P <<= 1, k++;
    	init(k);
    	for(R long long i = 0; i < P; ++i) x[i] = a[i]*a[i]*a[i], y[i] = b[i];
    	solve(1, P);
    	for(R long long i = 0; i < P; ++i) x[i] = a[i], y[i] = b[i]*b[i]*b[i];
    	solve(1, P);
    	for(R long long i = 0; i < P; ++i) x[i] = a[i]*a[i], y[i] = b[i]*b[i];
    	solve(-2, P);
    	for(R long long i = lent-1; i < lens; ++i) if(is0(ans[i])) tot++;
    	printf("%d
    ", tot);
    	return 0;
    }
    
  • 相关阅读:
    hbase 导入导出、hbase shell 基本命令。
    一道java基础面试题
    sqoop2报错
    测试往博客上放音乐
    java 压缩文件
    java 提取目录下所有子目录的文件到指定位置
    3.Git的常用操作
    2.Git客户端安装
    1.Git的由来
    『Spring』IOC创建对象的方式
  • 原文地址:https://www.cnblogs.com/heanda/p/12398591.html
Copyright © 2011-2022 走看看