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;
    }
  • 相关阅读:
    线程池
    交互
    Java类文件的结构详细介绍
    redis
    弹幕
    约瑟夫环问题
    Redis数据类型和应用场景
    Java集合类整体结构
    JDBC详细介绍
    Mybatis万能Map
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10431349.html
Copyright © 2011-2022 走看看