zoukankan      html  css  js  c++  java
  • 【题解】CF1129C Morse Code

    CF1129C Morse Code

    ( ext{Solution:})

    考虑直接 (O(n^2))(dp.) 如果没有重复的限制,那么有一个简单做法:

    依次加入 (i,) 枚举所有后缀 (j,) 大力 (dp) 出方案数。

    f[i][j]=Add(f[i][j],f[i-1][j],f[i-2][j],f[i-3][j],f[i-4][j])
    

    对应几种不同状况。那么如何考虑重复?

    考虑用哈希判重。对于枚举到的所有后缀,考虑每次 (dp) 完就直接在哈希表里面记录对应的 (dp) 值。这样就可以达到判重的目的。

    但是这里要注意,这里的判重一定要准确对应到字符串上,而不仅仅是一个对于后缀区间上的哈希。一定是要在字符上的重复才不计数,并且:

    对应一定要按顺序划分,比如 设 (f[i][j]) 是以 (i) 为结尾的区间,那么转移应当从右往左划分。而对于 (dp) 值的获取直接从之前的哈希表里面找即可。

    注意哈希表的实现,卡空间的同时注意时间和空间的常数。这题双哈希过不了,单哈希需要配合哈希表。

    #pragma GCC optimize(3)
    #pragma GCC optimize(2)
    #pragma GCC target("avx,sse2,sse3,sse4,mmx")
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("inline")
    #pragma GCC optimize("-fgcse")
    #pragma GCC optimize("-fgcse-lm")
    #pragma GCC optimize("-fipa-sra")
    #pragma GCC optimize("-ftree-pre")
    #pragma GCC optimize("-ftree-vrp")
    #pragma GCC optimize("-fpeephole2")
    #pragma GCC optimize("-ffast-math")
    #pragma GCC optimize("-fsched-spec")
    #pragma GCC optimize("unroll-loops")
    #pragma GCC optimize("-falign-jumps")
    #pragma GCC optimize("-falign-loops")
    #pragma GCC optimize("-falign-labels")
    #pragma GCC optimize("-fdevirtualize")
    #pragma GCC optimize("-fcaller-saves")
    #pragma GCC optimize("-fcrossjumping")
    #pragma GCC optimize("-fthread-jumps")
    #pragma GCC optimize("-funroll-loops")
    #pragma GCC optimize("-fwhole-program")
    #pragma GCC optimize("-freorder-blocks")
    #pragma GCC optimize("-fschedule-insns")
    #pragma GCC optimize("inline-functions")
    #pragma GCC optimize("-ftree-tail-merge")
    #pragma GCC optimize("-fschedule-insns2")
    #pragma GCC optimize("-fstrict-aliasing")
    #pragma GCC optimize("-fstrict-overflow")
    #pragma GCC optimize("-falign-functions")
    #pragma GCC optimize("-fcse-skip-blocks")
    #pragma GCC optimize("-fcse-follow-jumps")
    #pragma GCC optimize("-fsched-interblock")
    #pragma GCC optimize("-fpartial-inlining")
    #pragma GCC optimize("no-stack-protector")
    #pragma GCC optimize("-freorder-functions")
    #pragma GCC optimize("-findirect-inlining")
    #pragma GCC optimize("-fhoist-adjacent-loads")
    #pragma GCC optimize("-frerun-cse-after-loop")
    #pragma GCC optimize("inline-small-functions")
    #pragma GCC optimize("-finline-small-functions")
    #pragma GCC optimize("-ftree-switch-conversion")
    #pragma GCC optimize("-foptimize-sibling-calls")
    #pragma GCC optimize("-fexpensive-optimizations")
    #pragma GCC optimize("-funsafe-loop-optimizations")
    #pragma GCC optimize("inline-functions-called-once")
    #pragma GCC optimize("-fdelete-null-pointer-checks")
    #include<bits/stdc++.h>
    using namespace std;
    #define ull unsigned long long
    const int N=3050;
    ull f[N];
    int m;
    const ull base=7;
    ull hhash[N],fac[N];
    const unsigned long long mod=1e9+7;
    const unsigned long long P=9876553+10000;
    inline int Add(int x,int y,int M=mod){return (x+y)%M;}
    inline int Mul(int x,int y,int M=mod){return 1ll*x*y%M;}
    inline int Max(int x,int y){return x>y?x:y;}
    inline int Min(int x,int y){return x<y?x:y;}
    char s[N];
    inline ull Get(int l,int r){
    	if(l>r)return 0;
    	ull res=hhash[r]-hhash[l-1]*fac[r-l+1];
    	return res;
    }
    inline bool check(int a,int b,int c,int d){
    	if(s[a]=='0'&&s[b]=='0'&&s[c]=='1'&&s[d]=='1')return false;
    	if(s[a]=='0'&&s[b]=='1'&&s[c]=='0'&&s[d]=='1')return false;
    	if(s[a]=='1'&&s[b]=='1'&&s[c]=='1'&&s[d]=='0')return false;
    	if(s[a]=='1'&&s[b]=='1'&&s[c]=='1'&&s[d]=='1')return false;
    	return true;
    }
    typedef pair<unsigned long long,unsigned long long> pr;
    #define fi first
    #define se second
    #define mk make_pair
    struct B{
    	vector<pr>h[P+10];
    	void Insert(unsigned long long x,int val){
    		int pos=x%P;
    		for(auto v:h[pos]){if(v.fi==x)return;}
    		h[pos].push_back(mk(x,val));
    	}
    	int operator[](const unsigned long long x){
    		int pos=x%P;
    		for(auto v:h[pos]){if(v.fi==x)return v.se;}
    		return 0;
    	}
    }viss;
    int a[N];
    inline void write(long long x){
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    }
    int main(){
    // 	freopen("in.txt","r",stdin);
    	cin>>m;
    	fac[0]=1;
    	for(int i=1;i<=m;++i)fac[i]=fac[i-1]*base;
    	for(int i=1;i<=m;++i)cin>>s[i];
    	for(int i=1;i<=m;++i)a[i]=s[i]-'0'+1;
    	hhash[0]=0;
    	for(int i=1;i<=m;++i)hhash[i]=hhash[i-1]*base+a[i]+1;
    	viss.Insert(0,1);
    	long long ans=0;
    	for(int i=1;i<=m;++i){
    		for(int j=1;j<=i;++j){
    			if(viss[Get(j,i)])continue;
    			if(i>=j)f[j]=Add(f[j],viss[Get(j,i-1)]);
    			if(i-1>=j)f[j]=Add(f[j],viss[Get(j,i-2)]);
    			if(i-2>=j)f[j]=Add(f[j],viss[Get(j,i-3)]);
    			if(i-3>=j&&check(i-3,i-2,i-1,i))f[j]=Add(f[j],viss[Get(j,i-4)]);
    			ans=Add(ans,f[j]);viss.Insert(Get(j,i),f[j]);
    		}
    		for(int j=1;j<=i;++j)f[j]=0;
    		write(ans);putchar('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
    Data Structure and Algorithm
  • 原文地址:https://www.cnblogs.com/h-lka/p/15365199.html
Copyright © 2011-2022 走看看