zoukankan      html  css  js  c++  java
  • 「hihoCoder1869」Items

    「hihoCoder1869」Items

    problem

    官方题解

    Solutions

    很妙的一个做法

    首先很容易想到(O(nm))的01背包,显然不能满足要求

    每次加入一个数(a)时,我们都会用会用区间([0,m-1-a])更新([a,m-1]),用([m-a,m-1])更新([0,a-1])

    对于上面的每一组区间而言,两个值不同的对应位置前面一定有一段相同的子串。

    因此我们二分某两个对应区间的lcp的长度,可以通过哈希判定相同。然后对值不同的对应位置记录能否成功转移,再逐步向后执行相同的操作。

    最后进行修改,hash可以利用树状数组来维护。

    这样我们就成功地把很多不必要的操作省去从而达到降低时间复杂度的目的

    具体复杂度和证明可以看官方题解

    Code

    不知道为什么跑得很慢,尚不清楚是否是对题解的理解产生了偏差

    欢迎指正

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #define lowbit(t) ((t)&(-(t)))
    #define inv(x) (fastpow((x),mod-2))
    using namespace std;
    typedef long long ll;
    
    template <typename T> void read(T &t)
    {
        t=0;int f=0;char c=getchar();
        while(!isdigit(c)){f|=f=='-';c=getchar();}
        while(isdigit(c)){t=t*10+c-'0';c=getchar();}
        if(f)t=-t;
    }
    
    const ll mod=998244353,base=3;
    const int maxn=300000+5,maxm=300000+5;
    
    int n,m,q;
    ll pow3[maxm],inv3[maxm];
    int dp[maxm];
    struct BitTree
    {
        ll c[maxm];
        void Add(int x,ll v)
        {
            for(;x<=m;x+=lowbit(x))
                c[x]=(c[x]+v)%mod;
        }
        ll Query(int l,int r)
        {
            ll re=0;
            --l;
            for(;r;r-=lowbit(r))
                re=(re+c[r])%mod;
            for(;l;l-=lowbit(l))
                re=(re-c[l]+mod)%mod;
            return re;
        }
    }t;
    
    ll fastpow(ll a,ll b)
    {
        ll re=1,base=a;
        while(b)
        {
            if(b&1)
                re=re*base%mod;
            base=base*base%mod;
            b>>=1;
        }
        return re;
    }
    
    void Inti()
    {
        pow3[m]=1,inv3[m]=1,inv3[m-1]=inv(3);
        for(register int i=m-1;i;--i)
        {
            pow3[i]=(pow3[i+1]*3)%mod;
            inv3[i]=(inv3[i+1]*inv3[m-1])%mod;
        }
    }
    
    inline ll Hash(int l,int r)
    {
        return t.Query(l,r)*inv3[r]%mod;
    }
    
    inline bool Check(int la,int ra,int lb,int rb)
    {
        return Hash(la,ra)==Hash(lb,rb);
    }
    
    int BS(int l,int r,int b1,int b2)
    {
        int ans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(Check(b1,b1+mid-1,b2,b2+mid-1))
                ans=mid,l=mid+1;
            else
                r=mid-1;
        }
        return ans;
    }
    
    int update[maxm];
    int main()
    {
        read(n),read(m);
        Inti();
        dp[1]=1;
        t.Add(1,pow3[1]);
        for(register int i=1;i<=n;++i)
        {
            int a;
            read(a);
            int offset=0;
            update[0]=0;
            while(!Check(1+offset,m-a,a+1+offset,m))
            {
                int len=BS(1,m-a-offset,1+offset,a+1+offset);
                if(dp[1+offset+len] && !dp[a+1+offset+len])
                    update[++update[0]]=a+1+offset+len;
                offset+=len+1;
            }
            offset=0;
            while(!Check(m-a+1+offset,m,1+offset,a))
            {
                int len=BS(1,a-offset,m-a+1+offset,1+offset);
                if(dp[m-a+1+offset+len] && !dp[1+offset+len])
                    update[++update[0]]=1+offset+len;
                offset+=len+1;
            }
            for(register int j=1;j<=update[0];++j)
    		{
    			t.Add(update[j],pow3[update[j]]);
    			dp[update[j]]=1;
    		}
        }
        read(q);
        while(q--)
        {
            int x;
            read(x);
            printf(dp[x+1]?"YES
    ":"NO
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    hibernate持久化框架
    spring之AOP
    spring之bean
    spring之IOC
    pdf文件工具typora
    vsCode写vue项目一键生成.vue模板
    微信小程序瀑布流
    小程序接入阿拉丁
    小程序引入背景图片不显示问题解决
    Mac OS下使用rz和sz
  • 原文地址:https://www.cnblogs.com/lizbaka/p/10575239.html
Copyright © 2011-2022 走看看