zoukankan      html  css  js  c++  java
  • bzoj4532: [BeiJing2014 WinterCamp] 珠链

    我TM真是读题之神zzzzzzz 只能在头尾取啊233333

    R-L+1这么小肯定是用来枚举的

    然后那个约数个数是强行拼起来搞我的,弄那么多花里胡哨的东西很容易忽略什么,预处理一下就变成点权了

    主要问题在符合规范,两两每个位置都不一样

    容易发现每个位置放过一个字母以后就不能再放了,所以最多放52次

    由于枚举了段的长度,那么可以把序列按对长度取模分组,只有相同组的有可能放在不同段的同一位置

    考虑枚举起点,处理出最远能够不重复的终点,稍微计算一下里面的段数更新一下答案就好了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int _=1e2;
    const int maxn=5*1e5+_;
    int pr,prime[maxn],qc[maxn];bool pv[maxn];
    LL yc[maxn]; 
    void yu()
    {
        pr=0;yc[1]=1;
        for(int i=2;i<maxn;i++)
        {
            if(pv[i]==false)
                prime[++pr]=i,yc[i]=2,qc[i]=1;
            for(int j=1;j<=pr&&i*prime[j]<maxn;j++)
            {
                pv[i*prime[j]]=true;
                if(i%prime[j]==0)
                {
                    qc[i*prime[j]]=qc[i]+1;
                    yc[i*prime[j]]=yc[i]/(qc[i]+1)*(qc[i]+2);
                    break;
                }
                else 
                {
                    qc[i*prime[j]]=1;
                    yc[i*prime[j]]=yc[i]*2;
                }
            }
            yc[i]+=yc[i-1];
        }
    }
    
    
    int n,S,a[maxn];char ss[maxn];
    bool b[maxn][60];
    LL calc(int L)
    {
        int st,ed=0; LL ret=0;
        for(st=1;st<=n;st++)
        {
            while(ed<n)
            {
                ed++;
                if(b[ed%L][a[ed]]==false)
                    b[ed%L][a[ed]]=true;
                else {ed--;break;}
            }
            int u=(ed-st+1)/L;//段数
            if(u>=S)
            {
                u=st+L*u-1;//真正合法右界 
                ret=max(ret,yc[u]-yc[st-1]);
            }
            b[st%L][a[st]]=false;
        }
        while(st<=ed)b[st%L][a[st]]=false,st++;
        
        return ret;
    }
    
    int main()
    {
        yu();
        int LLLL,RRRR;
        scanf("%d%d%d%d%s",&n,&LLLL,&RRRR,&S,ss+1);
        for(int i=1;i<=n;i++)
            if('a'<=ss[i]&&ss[i]<='z')a[i]=ss[i]-'a'+1;
            else a[i]=ss[i]-'A'+27;
        
        LL ans=0;
        for(int i=LLLL;i<=RRRR;i++)ans=max(ans,calc(i));
        if(ans==0)puts("-1");
        else printf("%lld
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    一行代码更改博客园皮肤
    fatal: refusing to merge unrelated histories
    使用 netcat 传输大文件
    linux 命令后台运行
    .net core 使用 Nlog 配置文件
    .net core 使用 Nlog 集成 exceptionless 配置文件
    Mysql不同字符串格式的连表查询
    Mongodb between 时间范围
    VS Code 使用 Debugger for Chrome 调试vue
    css权重说明
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10431349.html
Copyright © 2011-2022 走看看