• 一道双哈希题,但是为什么TLE??2021山东icpc省赛 F题 Birthday Cake


    思维比较好想的hash,但是要双哈希

    于是要用map<pair<long long,long long>,int>

    AC代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<map>
    #include<cstring>
    using namespace std;
    const int MAXN = 4e5+77;
    string ss[MAXN],s[MAXN];
    map<pair<long long ,long long>,int>cs; 
    map<string,int>cnt;
    const long long BASE[2] = {12345,1234567};
    const long long MOD[2] = {1000000007,1000000009};
    long long inv_BASE[2]; 
    long long mc[2][MAXN];
    long long qpow(long long a,long long b,long long c){
    	long long res = 1;
    	for(;b;b>>=1,a = a * a % c){
    		if(b&1) res = res * a % c;
    	}
    	return res;
    }
    void pre(int n){
    	mc[0][0] = mc[1][0] = 1;
    	for(int i = 1;i <= n;i++) {
    		mc[0][i] = mc[0][i-1] * BASE[0] % MOD[0];
    		mc[1][i] = mc[1][i-1] * BASE[1] % MOD[1];
    	} 
    	inv_BASE[0] = qpow(BASE[0],MOD[0] - 2,MOD[0]);
    	inv_BASE[1] = qpow(BASE[1],MOD[1] - 2,MOD[1]);
    }
    pair<long long,long long>pp;
    void insert(string s){
    	long long res[2] = {0,0};
    	for(int e = 0;e < 2;e++){
    		for(int i = 0;s[i];i++){
    			res[e] = (res[e] * BASE[e] + s[i]) % MOD[e];
    		}
    	}
    	//cout<<"res0 " << res[0] << " res1 " << res[1] <<"\n";
    	pp.first = res[0];pp.second = res[1];
    	cs[pp]++;
    	cnt[s]++;
    }
    int n;
    long long ans = 0;
    void cal(string s){
    	long long hs1[2] = {0,0},hs2[2] = {0,0},hs3[2];
    	long long res[2] = {0,0};
    	for(int e = 0;e < 2;e++){
    		for(int i = 0;s[i];i++){
    			res[e] = (res[e] * BASE[e] + s[i]) % MOD[e];
    		}
    		hs3[e] = res[e];
    	}
    	long long ct = cnt[s];
    	for(int i = 0, j = s.length() - 1;j - i > 1;i++,j--){
    		for(int e = 0;e < 2;e++){
    			hs1[e] = (hs1[e] * BASE[e] + s[i]) % MOD[e];
    			hs2[e] = (hs2[e] + mc[e][i] * s[j]) % MOD[e];
    			hs3[e] = (hs3[e] - mc[e][j-i] * s[i] - s[j]) % MOD[e] * inv_BASE[e] % MOD[e];
    			hs3[e] = (hs3[e] + MOD[e]) % MOD[e];
    		}	
    		if(hs1[0] == hs2[0] && hs1[1] == hs2[1]){
    			pp.first = hs3[0],pp.second = hs3[1];
    			ans += 1ll * ct * cs[pp];//cs[pp]是map<pair<long long,long long>,int> 
    			//ans += 1ll * cnt[s] * cs[pp]; 
    		}
    	}
    }
    int main()
    {
    	pre(4e5+7);
    	cin>>n;
    	for(int i = 1;i <= n;i++){
    		cin>>s[i];
    		insert(s[i]);
    	}
    	for(int i = 1;i <= n;i++){
    		long long ct = cnt[s[i]];
    		if(ct){
    			ans += 1ll * ct * (ct-1) / 2;
    			cal(s[i]);
    			cnt[s[i]] = 0;
    		}
    	}
    	cout<<ans<<"\n";
    	return 0;
    }  
    

      

    但是这样是TLE的:

    void cal(string s){
    	long long hs1[2] = {0,0},hs2[2] = {0,0},hs3[2];
    	long long res[2] = {0,0};
    	for(int e = 0;e < 2;e++){
    		for(int i = 0;s[i];i++){
    			res[e] = (res[e] * BASE[e] + s[i]) % MOD[e];
    		}
    		hs3[e] = res[e];
    	}
    	//long long ct = cnt[s];
    	for(int i = 0, j = s.length() - 1;j - i > 1;i++,j--){
    		for(int e = 0;e < 2;e++){
    			hs1[e] = (hs1[e] * BASE[e] + s[i]) % MOD[e];
    			hs2[e] = (hs2[e] + mc[e][i] * s[j]) % MOD[e];
    			hs3[e] = (hs3[e] - mc[e][j-i] * s[i] - s[j]) % MOD[e] * inv_BASE[e] % MOD[e];
    			hs3[e] = (hs3[e] + MOD[e]) % MOD[e];
    		}	 
    		if(hs1[0] == hs2[0] && hs1[1] == hs2[1]){
    			pp.first = hs3[0],pp.second = hs3[1];
    			//ans += 1ll * ct * cs[pp];//cs[pp]是map<pair<long long,long long>,int> 
    			ans += 1ll * cnt[s] * cs[pp]; 
    		}
    	}
    }
    

      

    差别就在于cnt[s]是只访问一次和访问多次,为什么就TLE了

  • 相关阅读:
    swing如何让控件在窗口打开时,自动获得焦点
    获取list集合中重复的元素
    IDEA安装流程(IDEA安装步骤)
    tmux切换页,鼠标滚动
    prefix
    python换行
    安装pytorch方法,直接上官网!
    解压tar.gz文件
    安装boost
    pytorch将其他类型转为tensor torch.as_tensor()、torch.from_numpy()
  • 原文地址:https://www.cnblogs.com/ruanbaitql/p/15521263.html
Copyright © 2020-2023  润新知