zoukankan      html  css  js  c++  java
  • bzoj3207花神的嘲讽计划Ⅰ

    题意:http://www.lydsy.com/JudgeOnline/problem.php?id=3207

       给定一个原字符串和m个询问,每次查询原字符串[l,r]内是否包含给定字符串s (len(s)<=20且len(s)相同)

    sol  :考虑hash,将原串没len(s)位hash一次放入桶中,再将每次询问hash后在桶中查询(感觉很像rk-hash)

       因为每次[l,r]转移到[l,r±1]、[l±1,r]都是从桶中取出or放入一个数,复杂的O(1),可以使用莫队算法

       P.S.需要离散化而不能取模,否则memset复杂度爆炸

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define int long long
    using namespace std;
    const int Mx=100010;
    const int p=23333333LL;
    struct Node { int x,y,val,num; } str[Mx];
    bool cmp1 (Node a,Node b) { return a.x<b.x; }
    bool cmp2 (Node a,Node b) { return a.y<b.y; }
    int n,m,k,temp,a[Mx],h[Mx],ton[p+10],ans[Mx];
    signed main()
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        for(int i=1;i<=m;i++)
        {
            int Tmp[50],tmp=1;str[i].num=i;
            scanf("%lld%lld",&str[i].x,&str[i].y);
            for(int j=1;j<=k;j++) scanf("%lld",&Tmp[j]);
            for(int j=k;j>=1;j--) str[i].val+=tmp*Tmp[j],tmp*=37,tmp%=p,str[i].val%=p;
            if(i==1) temp=tmp/37;
        }
        for(int i=k,tmp=1;i>=1;i--) h[1]+=tmp*a[i],tmp*=37,tmp%=p,h[1]%=p;
        for(int i=k+1;i<=n;i++) h[i-k+1]=(((h[i-k]-(a[i-k]*temp))*37+a[i])%p+p)%p;
        sort(str+1,str+1+m,cmp1);
        for(int i=1;i<=m;i+=sqrt(m)) sort(str+i,str+min(m,i+(int)sqrt(m)),cmp2);
        for(int i=1;i<=m;i++)
        {
            if(i%(int)sqrt(m)==1||i==1)
            {
                memset(ton,0,sizeof(ton));
                for(int j=str[i].x;j<=str[i].y;j++) ton[(h[j]%p+p)%p]++;
            }
            else
            {
                for(int j=str[i-1].x,to=str[i].x;j!=to;)
                {
                    if(j<to) ton[(h[j]%p+p)%p]--,j++;
                    else j--,ton[(h[j]%p+p)%p]++;
                }
                for(int j=str[i-1].y,to=str[i].y;j!=to;)
                {
                    if(j<to) j++,ton[(h[j-k]%p+p)%p]++;
                    else ton[(h[j-k]%p+p)%p]--,j--;
                }
            }
            ans[str[i].num]=ton[str[i].val];
        }
        for(int i=1;i<=m;i++)
        {
            if(ans[i]==0) puts("Yes");
            else puts("No");
        }
        return 0;
    }
  • 相关阅读:
    Hamming Distance
    变量
    Jupyter Notebook 快捷键使用指南
    XPath使用总结
    selenium调用webdriver异常
    漏洞挖掘 | 远程WWW服务支持TRACE请求
    漏洞挖掘 | 点击劫持
    漏洞挖掘 | 目录浏览漏洞
    漏洞挖掘 | 弱口令漏洞
    浅谈Linux下/etc/passwd文件
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6336616.html
Copyright © 2011-2022 走看看