The Preliminary Contest for ICPC Asia Shanghai 2019 G. Substring (滑窗+哈希)

G. Substring

一直超时or超内存

然后一直改一直改 然后 是 答案错误

然后 然后 最后结论是哈希姿势不对

我在别的地方找了这个:

//https://www.cnblogs.com/napoleon_liu/archive/2010/12/29/1920839.html

uint32_t hash( uint32_t a)
{
   a = (a+0x7ed55d16) + (a<<12);
   a = (a^0xc761c23c) ^ (a>>19);
   a = (a+0x165667b1) + (a<<5);
   a = (a+0xd3a2646c) ^ (a<<9);
   a = (a+0xfd7046c5) + (a<<3); //
   a = (a^0xb55a4f09) ^ (a>>16);
   return a;
}

然后借用这个 我改了改

但是吧......  我用龙龙再取模 没去用unsigned  然后就答案错误

哎 吸取教训

哈希讲究正确姿势,数据就是力量。

然后  以前一直没意识到这件事

//超内存:
if(mp[x])mp[x]++;
//不会超内存
if(mp.count(x))mp[x]++;

然后......  哎

思路就是题解的思路。

一直超时超内存

结果做出来:3368ms 2132kb

题目给的是:10000ms 20480kb

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define debug printf("!");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=1e5+50;
const int inf=0x3f3f3f3f;

inline ull Gh(ull a)
{
    a+=14271;
    a=(a+0x7ed55d16)+(a<<12);
    a=(a^0xc761c23c)^(a>>19);
    a=(a+0x165667b1)+(a<<5);
    a=(a+0xd3a2646c)^(a<<9);
    a=(a+0xfd7046c5)+(a<<3);
    a=(a^0xb55a4f09)^(a>>16);
    return a;
}

inline ull Lh(ull a)
{
    a=Gh(a*INT_MAX);
    a=(a+0x7ecc5d16)+(a<<13);
    a=(a^0xc761c89c)^(a>>17);
    a=(a+0x315667b1)+(a<<7);
    a=(a+0xdfa26a6c)^(a<<11);
    a=(a+0xfd7b4aa5)+(a<<5);
    a=(a^0xb59b4e09)^(a>>12);
    return Gh(a);
}
inline ull Rh(ull a)
{
    a=Gh(a*a+31313);
    a=(a+0x8bd45d31)+(a<<16);
    a=(a^0x24bad623)^(a>>15);
    a=(a+0x971bfa3b)+(a<<7);
    a=(a+0x12abf315)^(a<<4);
    a=(a+0x2e4174bd)+(a<<7);
    a=(a^0xac5baef5)^(a>>14);
    return Gh(a);
}

char s[maxn],ts[maxn];
tr1::unordered_map<ull,int> mp;
ull anshs[20002];
int veclen[20002];
ull h;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll tlen;
        ull L,R,u,u1,u2,unext,chcut,chadd;
        int m,i,j,w,len,nextlen,up,tot=0;
        scanf("%s",s);
        len=strlen(s);
        scanf("%d",&m);
        for(i=0;i<m;i++)
        {
            scanf("%s",ts);
            tlen=strlen(ts);
            L=ts[0]-‘a‘;R=ts[tlen-1]-‘a‘;

            h=Lh(L)+Rh(R);
            for(j=0;j<tlen;j++)
            {
                u=ts[j]-‘a‘;
                h=h+Gh(u);
            }
            mp[h]=1;
            anshs[i]=h;
            veclen[i]=tlen;
        }
        sort(veclen,veclen+m);
        up=unique(veclen,veclen+m)-veclen;
        L=s[0]-‘a‘;R=s[veclen[0]-1]-‘a‘;
        unext=0;
        for(j=0;j<veclen[0];j++)
        {
            u=s[j]-‘a‘;
            unext=unext+Gh(u);
        }
        for(w=0;w<up;w++)
        {
            tlen=veclen[w];
            nextlen=veclen[w+1];
            if(tlen>len)break;
            for(j=0;j+tlen-1<len;j++)//长度滑窗
            {
                L=s[j]-‘a‘;R=s[j+tlen-1]-‘a‘;
                u1=Lh(L)+Rh(R);
                if(!j)u=unext;
                else
                {
                    chcut=s[j-1]-‘a‘;
                    chadd=R;
                    if(j+tlen-1<nextlen)
                    {
                        unext=unext+Gh(R);
                    }
                    u=u-Gh(chcut)+Gh(chadd);
                }
                if(mp.count(u+u1))mp[u+u1]++;
            }
        }
        for(i=0;i<m;i++)printf("%d\n",mp[anshs[i]]-1);
        mp.clear();
    }
}

哎...

原文地址:https://www.cnblogs.com/kkkek/p/11529899.html

时间: 2024-07-31 17:38:02

The Preliminary Contest for ICPC Asia Shanghai 2019 G. Substring (滑窗+哈希)的相关文章

The Preliminary Contest for ICPC Asia Shanghai 2019 C Triple(FFT+暴力)

The Preliminary Contest for ICPC Asia Shanghai 2019 C Triple(FFT+暴力) 传送门:https://nanti.jisuanke.com/t/41400 题意: 给你三个数组a,b,c,要你求有多少个三元组(i,j,k),使得 \[ \begin{array}{l}{\left|A_{i}-B_{j}\right| \leq C_{k}, \text { and }} \\ {\left|B_{j}-C_{k}\right| \leq

The Preliminary Contest for ICPC Asia Shanghai 2019

D. Counting Sequences I 暴力搜索. #include <bits/stdc++.h> using namespace std; typedef long long ll; const int MOD = 1000000007; map<vector<short>, short> m; vector<short> vec; void calc(int num1) { vector<short> tmp; if(num1) t

Digit sum-----The Preliminary Contest for ICPC Asia Shanghai 2019

A digit sum S_b(n)Sb?(n) is a sum of the base-bb digits of nn. Such as S_{10}(233) = 2 + 3 + 3 = 8S10?(233)=2+3+3=8, S_{2}(8)=1 + 0 + 0 = 1S2?(8)=1+0+0=1, S_{2}(7)=1 + 1 + 1 = 3S2?(7)=1+1+1=3. Given NN and bb, you need to calculate \sum_{n=1}^{N} S_b

01背包方案数(变种题)Stone game--The Preliminary Contest for ICPC Asia Shanghai 2019

题意:https://nanti.jisuanke.com/t/41420 给你n个石子的重量,要求满足(Sum<=2*sum<=Sum+min)的方案数,min是你手里的最小值. 思路: 从最大重量的石子开始背包,每次ans+=dp[j-v[i]]就行了. 1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0); 2 #include <cstdio>//sprintf islower isupper 3 #include &

给定进制下1-n每一位数的共享(Digit sum)The Preliminary Contest for ICPC Asia Shanghai 2019

题意:https://nanti.jisuanke.com/t/41422 对每一位进行找循环节规律就行了. 1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0); 2 #include <cstdio>//sprintf islower isupper 3 #include <cstdlib>//malloc exit strcat itoa system("cls") 4 #include <io

The Preliminary Contest for ICPC Asia Shanghai 2019 L. Digit sum

题目:https://nanti.jisuanke.com/t/41422 思路:预处理 #include<bits/stdc++.h> using namespace std; int dp[11][1000001]={0}; int main() { for(int i=2;i<=10;i++) { for(int j=1;j<=1000000;j++) { int t=j; int res=0; res=j%i; dp[i][j]=res+dp[i][j/i]+dp[i][j

The Preliminary Contest for ICPC Asia Shanghai 2019 B. Light bulbs

题目:https://nanti.jisuanke.com/t/41399 思路:差分数组 区间内操作次数为奇数次则灯为打开状态 #include<bits/stdc++.h> using namespace std; map<int,int>mp; int main() { int T; scanf("%d",&T); int n,m; int l,r; for(int i=1;i<=T;i++) { mp.clear(); scanf(&quo

The Preliminary Contest for ICPC Asia Shanghai 2019 D. Counting Sequences I

题目:https://nanti.jisuanke.com/t/41412思路:dfs           先取ai>2  2^12>3000 因此至多取11个 其余用1补           (3000*2)-(3000+2)=2998 那么需要加入2998个1 正好3000位 所以 3000是ai最大取值           计算ans时 有重复元素的排列组合 :如1112233 res=7!/(3!*2!*2!)           另外预处理阶乘及其逆元 #include<bit

The Preliminary Contest for ICPC Asia Shanghai 2019 J. Stone game

题目:https://nanti.jisuanke.com/t/41420 思路:当a(a∈S′)为最小值 如果Sum(S′)−a≤Sum(S−S′)成立 那么(∀t∈S′,Sum(S′)−t≤Sum(S−S′))恒成立            先算01背包方案数 再从小到大排序进行退背包 #include<bits/stdc++.h> using namespace std; const int mod=1e9+7; int a[400]; int dp[150001]; int main()