zoukankan      html  css  js  c++  java
  • BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4943

    http://uoj.ac/problem/315

    https://www.luogu.org/problemnew/show/P3823#sub

    题面太长自己看吧orz。

    参考:洛谷题解。

    用链表暴力维护每个蚯蚓,每次合并和分离只对k*k的元素有影响,哈希一下存起来query时候比较就好了。

    没了。

    (具体复杂度我不会证明,以及bzoj卡空间,正常的哈希表空间总觉得不能开如代码所示的这么小。)

    (自然溢出hash真的块)

    #include<cmath>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int N=2e5+5;
    const int K=50;
    const int mod=998244353;
    const int p=19260817;
    const int B=13;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct node{
        int nxt,cnt;
        ll w;
    }e[21000000];
    char s[10000005];
    int n,m,cnt,head[p+5],t[10],a[N];
    int nxt[N],pre[N];
    ull f[K*2+5],base[K+5];
    inline void add(ull w,int on){
        int u=w%p;
        for(int i=head[u];i;i=e[i].nxt){
        if(e[i].w==w){
            e[i].cnt+=on;return;
        }
        }
        e[++cnt].cnt=1;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;
    }
    inline int ask(ull w){
        int u=w%p;
        for(int i=head[u];i;i=e[i].nxt){
        if(e[i].w==w)return e[i].cnt;
        }
        return 0;
    }
    void merge(int x,int y){
        int l=K+1,r=K;
        memset(f,0,sizeof(f));
        for(int i=x;i&&l>1;i=pre[i])f[--l]=a[i];
        for(int j=y;j&&r<2*K;j=nxt[j])f[++r]=a[j];
        for(int i=l;i<=r;i++)f[i]+=f[i-1]*B;
        for(int i=l;i<=K;i++){
        for(int j=K+1;j<=min(r,i+K-1);j++){
            add(f[j]-f[i-1]*base[j-i+1],1);
        }
        }
        nxt[x]=y;pre[y]=x;
    }
    void split(int x,int y){
        int l=K+1,r=K;
        memset(f,0,sizeof(f));
        for(int i=x;i&&l>1;i=pre[i])f[--l]=a[i];
        for(int j=y;j&&r<2*K;j=nxt[j])f[++r]=a[j];
        for(int i=l;i<=r;i++)f[i]+=f[i-1]*B;
        for(int i=l;i<=K;i++){
        for(int j=K+1;j<=min(r,i+K-1);j++){
            add(f[j]-f[i-1]*base[j-i+1],-1);
        }
        }
        nxt[x]=0;pre[y]=0;
    }
    int query(int k){
        ll ans=1;ull val=0;int len=strlen(s+1);
        if(k==1)
        for(int i=1;i<=len;i++)
            ans=ans*t[s[i]-'0']%mod;
        else{
        for(int i=1;i<=len;i++){
            val=val*B+s[i]-'0';
            if(i>k)val-=base[k]*(s[i-k]-'0');
            if(i>=k)ans=ans*ask(val)%mod;
        }
        }
        return ans;
    }
    int main(){
        n=read(),m=read();
        base[0]=1;
        for(int i=1;i<=K;i++)base[i]=base[i-1]*B;
        for(int i=1;i<=n;i++){
        a[i]=read();t[a[i]]++;
        }
        for(int i=1;i<=m;i++){
        int op=read();
        if(op==1){
            int x=read(),y=read();
            merge(x,y);
        }
        if(op==2){
            int x=read();
            split(x,nxt[x]);
        }
        if(op==3){
            scanf("%s",s+1);
            int k=read();
            printf("%d
    ",query(k));
        }
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    owe的用法
    other,others,another,the other的区别
    国内顶尖的sql dba 团队招人。
    Sqler 工具更新
    2015 年个人计划
    在没Hadoop 、GP 前提下怎么进行实时数据统计。
    201407-至今
    Sqler-Cmd
    Sqler-Monitor
    SqlCmd -Windows Cluster Model
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9050287.html
Copyright © 2011-2022 走看看