• 双Hash--兔子与兔子



    很久很久以前,森林里住着一群兔子。
    有一天,兔子们想要研究自己的DNA序列。
    我们首先选取一个好长好长的DNA序列(小兔子是外星生物,DNA序列可能包含26个小写英文字母)。
    然后我们每次选择两个区间,询问如果用两个区间里的DNA序列分别生产出来两只兔子,这两个兔子是否一模一样。
    注意两个兔子一模一样只可能是他们的DNA序列一模一样。
    Input
    第一行输入一个DNA字符串S。
    第二行一个数字m,表示m次询问。
    接下来m行,每行四个数字l1,r1,l2,r2,分别表示此次询问的两个区间,注意字符串的位置从1开始编号。
    数据范围
    1≤length(S),m≤1000000
    Output
    对于每次询问,输出一行表示结果。
    如果两只兔子完全相同输出Yes,否则输出No(注意大小写)。
    Sample Input
    aabbaabb
    3
    1 3 5 7
    1 3 6 8
    1 2 1 2
    Sample Output
    Yes
    No
    Yes​

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 1000005
    typedef long long ll;
    //typedef long double ld;
    
    
    int n,m;
    char s[maxn];
    
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
        for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    
    struct hash_table
    {
    	int mod,base,power[maxn],h[maxn];
    	void build()
    	{
    		for (int i=1;i<=n;i++) 
    		   h[i]=1ll*h[i-1]*base%mod+s[i]-'a';
    		power[0]=1; 
    		for (int i=1;i<=n;i++) 
    		     power[i]=1ll*power[i-1]*base%mod;
    	}
    	bool check(int l1,int r1,int l2,int r2)
    	{
    		int len=r1-l1+1;
    		int h1=((h[r1]-1ll*h[l1-1]*power[len]%mod)+mod)%mod;
    		int h2=((h[r2]-1ll*h[l2-1]*power[len]%mod)+mod)%mod;
    		return h1==h2;
    	}
    }H1,H2;
    
    int main()
    {
    	H1.mod=998244353,H2.mod=666623333; H1.base=233,H2.base=431;
    	scanf("%s",s+1); n=strlen(s+1);
    	H1.build(),H2.build();
    	int id=0;
    	for (int T=read();T;T--)
    	{
    		++id;
    		int l1=read(),r1=read(),l2=read(),r2=read();
    		if (r1-l1+1!=r2-l2+1)
    		   {
    		         puts("No"); 
    				 continue;
    		   }
    		puts((H1.check(l1,r1,l2,r2)&&H2.check(l1,r1,l2,r2))?"Yes":"No");
    	}
        return 0;
    }
    

      

    单Hash

    //19260817
    #include<bits/stdc++.h>
    
    using namespace std;
    typedef unsigned long long ull;
    const int MAX=1000010;
    int mod=19260817;
    int n,length,q;
    int l1,r1,l2,r2;
    char a[MAX];
    ull sum[MAX];
    ull prime=131;
    ull power[MAX];
    ull cut(int l,int r) 
    {
    	return ((sum[r]-sum[l-1]*power[r-l+1])%mod+mod)%mod;
    }
    int main() {
    	scanf("%s",a+1);
    	scanf("%d",&q);
    	int num=strlen(a+1);
    	power[0]=1;
    	sum[0]=0;
    	for(int i=1; i<=1000000; i++)         
    	power[i]=(power[i-1]*prime)%mod;
    	for(int i=1; i<=num; i++)         
    	sum[i]=(sum[i-1]*prime+a[i]-'a')%mod;
    	while(q--)     
    	{
    		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
    		if(l1-r1!=l2-r2) 
    		{
    			puts("No");
    			continue;
    		}
    		if(cut(l1, r1)==cut(l2, r2))puts("Yes");
    		else puts("No");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Capture CIS:Capture was not found错误
    Memcached FAQ
    MTK META工具的使用和注意事项(MT6252)
    关于maps.google.com和ditu.google.cn地图偏差的说明
    VSS2005的二次开发
    同学PB经历的面试题
    给定一个字符串,包含中文字符和英文字符,取给定大小字节的子串。
    一些笔试题目和整理的答案 腾讯(Tencent)
    redhat面试题目
    Ubuntu远程链接Ubuntu之ssh
  • 原文地址:https://www.cnblogs.com/cutemush/p/12296071.html
Copyright © 2020-2023  润新知