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;
    }
    
  • 相关阅读:
    Day 03--设计与完善(一)
    Day 02--选题与设计(二)
    Day 01--选题与设计(一)
    课程设计第六天,08.24
    课程设计第五天,08.23
    课程设计第四天,08.22
    课程设计第三天,08.21
    软件课程设计第二天,08.20
    软件课程设计第一天
    旋转正方形
  • 原文地址:https://www.cnblogs.com/h-lka/p/15365199.html
Copyright © 2011-2022 走看看