zoukankan      html  css  js  c++  java
  • Bzoj4259: 残缺的字符串

    题面

    没有权限号的我当然选择luogu

    Sol

    假设没有通配符
    那么把(T)翻转
    (f[i]=sum_{j+k=i}[S[k]==T[j]])
    如果(f[i])(0)(i)之前的一一匹配
    那么可以给每个字符一个权值
    重新定义(f[i]=sum_{j+k=i}(S[k]-T[j])^2)
    就可以(FFT)

    然后有通配符,设权值为(0)
    再定义
    (f[i]=sum_{j+k=i}(S[k]-T[j])^2S[k]T[j])

    然后拆开(FFT)就可以了

    # include <bits/stdc++.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    
    template <class Int>
    IL void Input(RG Int &x){
    	RG int z = 1; RG char c = getchar(); x = 0;
    	for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    	x *= z;
    }
    
    const int maxn(3e5 + 5);
    const int oo(1e9);
    const double pi(acos(-1));
    
    int n, m, k, r[maxn << 2], len, cnt, v1[maxn], v2[maxn], ans[maxn];
    char s[maxn], t[maxn];
    
    struct Complex{
    	double real, image;
    
    	IL Complex(){
    		real = image = 0;
    	}
    	
    	IL Complex(RG double a, RG double b){
    		real = a, image = b;
    	}
    
    	IL Complex operator +(RG Complex b){
    		return Complex(real + b.real, image + b.image);
    	}
    
    	IL Complex operator -(RG Complex b){
    		return Complex(real - b.real, image - b.image);
    	}
    
    	IL Complex operator *(RG Complex b){
    		return Complex(real * b.real - image * b.image, real * b.image + image * b.real);
    	}
    
    	IL Complex operator *(RG int b){
    		return Complex(real * b, image * b);
    	}
    } a[maxn << 2], b[maxn << 2], w[maxn << 2], c[maxn << 2];
    
    IL void FFT(RG Complex *p, RG int opt){
    	for(RG int i = 0; i < len; ++i) if(r[i] < i) swap(p[i], p[r[i]]);
    	for(RG int i = 1; i < len; i <<= 1)
    		for(RG int j = 0, l = i << 1; j < len; j += l){
    			for(RG int k = 0; k < i; ++k){
    				RG Complex wn = Complex(w[len / i * k].real, w[len / i * k].image * opt);
    				RG Complex x = p[k + j], y = wn * p[k + j + i];
    				p[k + j] = x + y, p[k + j + i] = x - y;
    			}
    		}
    }
    
    IL void Prepare(){
    	RG int l = 0, tmp = m + n - 1;
    	for(len = 1; len < tmp; len <<= 1) ++l;
    	for(RG int i = 0; i < len; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
    	for(RG int i = 1; i <= len; i <<= 1)
    		for(RG int k = 0; k < i; ++k)
    			w[len / i * k] = Complex(cos(pi / i * k), sin(pi / i * k));
    }
    
    int main(RG int argc, RG char* argv[]){
    	Input(m), Input(n), scanf(" %s %s", t, s);
    	reverse(t, t + m), Prepare();
    	for(RG int i = 0; i < n; ++i) v1[i] = s[i] == '*' ? 0 : s[i] - 'a' + 1;
    	for(RG int i = 0; i < m; ++i) v2[i] = t[i] == '*' ? 0 : t[i] - 'a' + 1;
    	
    	for(RG int i = 0; i < n; ++i) a[i].real = v1[i] * v1[i] * v1[i];
    	for(RG int i = 0; i < m; ++i) b[i].real = v2[i];
    	FFT(a, 1), FFT(b, 1);
    	for(RG int i = 0; i < len; ++i) c[i] = c[i] + a[i] * b[i], a[i] = b[i] = Complex(0, 0);
    	
    	for(RG int i = 0; i < n; ++i) a[i].real = v1[i] * v1[i] << 1;
     	for(RG int i = 0; i < m; ++i) b[i].real = v2[i] * v2[i];
    	FFT(a, 1), FFT(b, 1);
    	for(RG int i = 0; i < len; ++i) c[i] = c[i] - a[i] * b[i], a[i] = b[i] = Complex(0, 0);
    	
    	for(RG int i = 0; i < n; ++i) a[i].real = v1[i];
    	for(RG int i = 0; i < m; ++i) b[i].real = v2[i] * v2[i] * v2[i];
    	FFT(a, 1), FFT(b, 1);
    	for(RG int i = 0; i < len; ++i) c[i] = c[i] + a[i] * b[i];
    	
    	FFT(c, -1);
    	for(RG int i = m - 1; i < n; ++i)
    		if(!(int(c[i].real / len + 0.5))) ans[++cnt] = i;
    	printf("%d
    ", cnt);
    	for(RG int i = 1; i <= cnt; ++i) printf("%d ", ans[i] - m + 2);
    	return puts(""), 0;
    }
    
    
  • 相关阅读:
    C# NPOI 导入与导出Excel文档 兼容xlsx, xls(xf13中已经引用了xlsx的npoi)
    ASP.Net超时时间已到解决办法-
    解决SqlDataSource连接超时的问题
    SqlDataSource控件超时的困惑
    Redis+Keepalived
    Linux Ubuntu 16.04 安装步骤+远程环境
    JDK 安装
    Maven 安装
    CAT 默认密码修改
    CAT 监控搭建
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8820748.html
Copyright © 2011-2022 走看看