• 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;
    }
  • 相关阅读:
    容易混淆的JavaScript基础知识之语法部分
    CSS入门基础学习一
    HTML基础入门学习准备篇
    HTML基础入门学习
    数据结构绪论
    CSS入门基础学习二
    JavaScript学习第一篇
    CSS/CSS3常用的样式
    vs 发生异常时不能被捕获
    c# 反射
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10431349.html
Copyright © 2020-2023  润新知