• 2017.10.19 模拟赛


    题目链接

    T1

    经过打表发现f(x)=x (x>=2) f(1)=2;

    然后问题就变为 ∑f(i)^k

    拉格朗日插值法。。学习地址

    #include <cstdio>
    #include <cctype>
    #define Mod 998244353
    
    inline void read(register int &x)
    {
        register char ch=getchar();
        for(x=0;!isdigit(ch);ch=getchar());
        for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    }
    int l,r,k,ans;
    inline int ksm(register int a,register int b)
    {
        int r=1,base=a;
        for(;b;b>>=1,base=1ll*base*base%Mod)
         if(b&1) r=1ll*r*base%Mod;
        return r%Mod;
    }
    int main(int argc,char *argv[])
    {
        freopen("count.in","r",stdin);
        freopen("count.out","w",stdout);
        scanf("%d%d%d",&l,&r,&k);
        for(register int i=l;i<=r;++i)
        {
            register int f;
            if(i==1||i==2) f=2;
            else f=i;
            ans=(ans%Mod+ksm(f,k))%Mod;
        }
        printf("%d
    ",ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    考场20分代码
    #include <cstring>
    #include <ctime>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
     
    using namespace std;
     
    const int Mod=998244353;
    const int MAXK=1000000;
     
    int power(int x,int k)
    {
        int ret=1;
        while (k)
        {
            if (k&1) ret=1LL*ret*x%Mod;
            x=1LL*x*x%Mod;
            k>>=1;
        }
        return ret;
    }
     
    int k;
     
    int f[MAXK+10];
     
    int pre[MAXK+10],suf[MAXK+10];
     
    int jc[MAXK+10],K[MAXK+10];
     
    int cnt(int n)
    {
        if (n==0) return 0;
        int ans=0;
        if (n<=k+10 || n<=MAXK)
        {
            for (int i=1; i<=n; i++) ans=(K[i]+ans)%Mod;
        }
        else
        {
            pre[0]=1;
            for (int i=1; i<=k+2; i++) pre[i]=1LL*pre[i-1]*(n-i)%Mod;
     
            suf[k+3]=1;
            for (int i=k+2; i>=1; i--) suf[i]=1LL*suf[i+1]*(n-i)%Mod;
     
            int l=k+1,r=0,flag=((k+1)&1)?(-1):(1);
            for (int i=1; i<=k+2; i++)
            {
                int s=1LL*pre[i-1]*suf[i+1]%Mod,m=1LL*(flag*jc[l]+Mod)*jc[r]%Mod;
                ans=(1LL*f[i]*s%Mod*power(m,Mod-2)%Mod+ans)%Mod;
                l--;
                r++;
                flag*=-1;
            }
        }
        ans=((ans+K[2])%Mod-1+Mod)%Mod;
        return ans;
    }
     
    int L,R;
     
    void init()
    {
        cin>>L>>R>>k;
        for (int i=1; i<=MAXK+5; i++) K[i]=power(i,k);
     
        jc[0]=1;
        for (int i=1; i<=k+2; i++) jc[i]=1LL*jc[i-1]*i%Mod;
        for (int i=1; i<=k+2; i++) f[i]=(f[i-1]+K[i])%Mod;
     
        cout<<(cnt(R)-cnt(L-1)+Mod)%Mod;
        return ;
    }
     
    int main()
    {
        freopen("count.in","r",stdin);
        freopen("count.out","w",stdout);
        init();
        fclose(stdin);
        fclose(stdout);
        //fprintf(stderr,"%.3lf
    ",1.0*clock()/(1.0*CLOCKS_PER_SEC));
        return 0;
    }
    std

    T2

    题意转化为求最大的区间长度使得这段区间和减k>=0
    首先做前缀和,可知若当前到了k,i<j<k && sum[i]<sum[j]则j一定不可能比i更优
    用单调栈维护这个过程。然后倒序更新答案即可。

    #include<cstdlib>
    #include<cstdio>
    #include<cctype>
    #define N 1000005
    typedef long long LL;
    int n,m,len,maxv,a[N];
    LL sum[N];
    inline void read(int &x)
    {
        register char ch=getchar();
        for(x=0;!isdigit(ch);ch=getchar());
        for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    }
    inline int max(int a,int b) {return a>b?a:b;}
    int main()
    {
        freopen("blocks.in","r",stdin);
        freopen("blocks.out","w",stdout);
        read(n);read(m);
        for(int i=1;i<=n;i++)
        {
            read(a[i]);
            sum[i]=sum[i-1]+a[i];
            maxv=max(maxv,a[i]);
        }
        for(int k,i=1;i<=m;i++)
        {
            read(k);
            if(k>maxv) {i==m?printf("0
    "):printf("0 ");continue;} 
            for(register int l=1;l<=n;++l)
                for(register int r=l;r<=n;++r)
                {
                    int tmp=r-l+1;
                    if((sum[r]-sum[l-1]-tmp*k)>=0) len=max(len,tmp);
                }
            i==m?printf("%d
    ",len):printf("%d ",len);len=0;
        }
        fclose(stdin); fclose(stdout);
        return 0;
    }
    考场40分代码
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 1000007
    
    using namespace std;
    long long sum[N];
    int a[N],st[N],top,n,m,cnt;
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    void solve(int k)
    {
        top=1;int res=0;
        for(int i=1;i<=n;i++) 
        {
            sum[i]=sum[i-1]+a[i]-k;
            if(!top || sum[st[top]]>sum[i]) st[++top]=i;
        }
        for(int i=n;i>=1;i--) 
        {
            while(top && sum[i]>=sum[st[top]]) top--;
            res=max(res,i-st[top+1]);
        }
        printf("%d ",res);
    }
    
    int main()
    {
        freopen("blocks.in","r",stdin);
        freopen("blocks.out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        while(m--) solve(read());
        return 0;
    }
    std

    T3

    将字符串倒序插入trie树,问题就转换成了若干字符串结束的LCA深度
    倍增维护LCA,每插入一个字符串,处理一次fa数组就可以了
    当然这题也可以哈希+二分

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    #define N 50005
    #define L 1000005
    using namespace std;
    inline void read(int &x)
    {
        register char ch=getchar();
        for(x=0;!isdigit(ch);ch=getchar());
        for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    }
    int n,m,a[N],len[N];
    string str[N];
    inline int min(int a,int b) {return a>b?b:a;}
    int main(int argc,char *argv[])
    {
        freopen("biology.in","r",stdin);
        freopen("biology.out","w",stdout);
        read(n);read(m);
        for(int i=1;i<=n;++i) cin>>str[i],len[i]=str[i].length();
        for(register int opt,x;m--;)
        {
            read(opt);
            if(opt==1) cin>>str[++n],len[n]=str[n].length();
            else 
            {
                read(x);
                int limit=0x7fffffff;
                for(int i=1;i<=x;++i) read(a[i]),limit=min(limit,len[a[i]]);
                register int ans=limit;
                for(register int i=0;i<=limit;++i)
                {
                    string s=str[a[1]];
                    register char ch=s[len[a[1]]-i-1];
                    bool flag=false;
                    for(register int j=2;j<=x;++j)
                    {
                        string y=str[a[j]];
                        if(y[len[a[j]]-i-1]!=ch)
                        {
                            flag=true;
                            break;
                        }
                    }
                    if(flag)
                    {
                        ans=i;
                        break;
                    }
                }
                printf("%d
    ",ans);
            }
        }
        fclose(stdin); fclose(stdout);
        return 0;
    }
    考场60分代码
    #include <cstring>
    #include <cstdio>
    #include <cctype>
    #define N 1000010
    int n,m,tot=1,trie[N][28],dad[N][25],pos[N],dep[N];
    char s[10005];
    void ins(int num)
    {
        int p=1,l=strlen(s+1);
        for(int i=l;i;--i)
        {
            int id=s[i]-'a';
            if(!trie[p][id])
            {
                trie[p][id]=++tot;
                dep[tot]=dep[p]+1;dad[tot][0]=p;
                for(int j=1;j<=20;++j) dad[tot][j]=dad[dad[tot][j-1]][j-1];
            }
            p=trie[p][id];
        }
        pos[num]=p;
    }
    void swap(int &m,int &n)
    {
        int tmp=n;
        n=m;
        m=tmp;
    }
    int lca(int x,int y)
    {
        if(dep[x]>dep[y]) swap(x,y);
        for(int i=20;i>=0;--i) 
        if(dep[dad[y][i]]>=dep[x])
         y=dad[y][i];
        if(x==y) return x;
        for(int i=20;i>=0;--i) 
        if(dad[y][i]!=dad[x][i])
         y=dad[y][i],x=dad[x][i];
        return dad[x][0];
    }
    int main(int argc,char *argv[])
    {
        freopen("biology.in","r",stdin);
        freopen("biology.out","w",stdout);
        scanf("%d%d",&n,&m);
        dep[0]=-1;
        for(int i=1;i<=n;++i) scanf("%s",s+1),ins(i);
        for(int opt,x,y,v;m--;)
        {
            scanf("%d",&opt);
            if(opt==1)
            {
                scanf("%s",s+1);
                ins(++n);
            }
            else
            {
                scanf("%d%d",&x,&y);
                int z=pos[y];
                for(int i=2;i<=x;++i)
                {
                    scanf("%d",&v);
                    z=lca(z,pos[v]);
                }
                printf("%d
    ",dep[z]);
            }
        }
        fclose(stdin); fclose(stdout);
        return 0;
    }
    std
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    typedef unsigned long long ll;
    
    const int maxlen=1000005,maxn=150005,hpos=29;
    
    int n,m,S[maxn],T[maxn],len[maxn],nowlen,top,Stack[maxn];
    
    char Arc[maxlen];
    
    ll Hash[maxlen];
    
    inline void read(int &now)
    {
        char Cget;
        now=0;
        while((Cget=getchar())>'9'||Cget<'0');
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    
    inline bool check(int lit)
    {
        ll tmp=Hash[T[Stack[1]]-lit+1];
        for(int i=2;i<=top;i++)
            if(Hash[T[Stack[i]]-lit+1]!=tmp)
                return false;
        return true;
    }
    
    int main()
    {
    //    freopen("data.txt","r",stdin);
        freopen("biology.in","r",stdin);
        freopen("biology.out","w",stdout);
        read(n);
        read(m);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",Arc+nowlen);
            len[i]=strlen(Arc+nowlen);
            S[i]=nowlen;
            T[i]=nowlen+len[i]-1;
            nowlen+=len[i];
            Hash[T[i]]=Arc[T[i]]-'a'+1;
            for(int v=T[i]-1;v>=S[i];v--)
                Hash[v]=Hash[v+1]*hpos+(Arc[v]-'a'+1);
        }
        for(int i=1,op,l,r,mid,res;i<=m;i++)
        {
            read(op);
            if(op==1)
            {
                ++n;
                scanf("%s",Arc+nowlen);
                len[n]=strlen(Arc+nowlen);
                S[n]=nowlen;
                T[n]=nowlen+len[n]-1;
                nowlen+=len[n];
                Hash[T[n]]=Arc[T[n]]-'a'+1;
                for(int v=T[n]-1;v>=S[n];v--)
                    Hash[v]=Hash[v+1]*hpos+(Arc[v]-'a'+1);
            }
            else
            {
                read(top);
                l=1,r=maxlen,mid,res=0;
                for(int v=1;v<=top;v++)
                {
                    read(Stack[v]);
                    r=std::min(r,len[Stack[v]]);
                }
                while(l<=r)
                {
                    mid=l+r>>1;
                    if(check(mid))
                    {
                        res=mid;
                        l=mid+1;
                    }
                    else
                        r=mid-1;
                }
                printf("%d
    ",res);
            }
        }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    某m姓大佬的hash
  • 相关阅读:
    apiClould微信三方登录,qq三方登录
    微信小程序 使用环信聊天工具
    某些控件的应用
    记事本(查找与替换)
    记事本部分功能
    Winform——计算器进制转换
    Winform——计算器
    汉企C#面向对象——继承Practice
    汉企C#面向对象——继承
    二分法
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7692354.html
Copyright © 2020-2023  润新知