zoukankan      html  css  js  c++  java
  • 珍珠项链 Beads

    https://loj.ac/problem/2427

    题目描述

      给出一段序列(A),求一个(k)使将序列(A)分为(k)段(不是倍数最后一段舍去)不同的段数最多。一个串的反转和它本身相同。

    思路

      这道题(A)的长度并不大,我们可以暴力枚举(k),对于每个(k)计算不同串的数目,再更新答案。需要注意这里并没有说一个串与它的顺序无关,二只是与它的反转有关,我们只要正反处理两次(Hash)值即可。不过这道题有点卡单(Hash),最好用双(Hash),不过我懒得写了,调一调(b)(A)了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    const ull p=10000019;
    const ull MAXN=2e5+10;
    ull sum1[MAXN],sum2[MAXN],power[MAXN],ans[MAXN],n,a[MAXN];
    ull f_hash(ull l,ull r,bool f)
    {
        if(f)return sum1[r]-sum1[l-1]*power[r-l+1];
        else return sum2[l]-sum2[r+1]*power[r-l+1];
    }
    set<ull>s;
    ull cal(int k)
    {
        s.clear();
        for(int i=1;i+k-1<=n;i+=k)
        {
            ull tmp=min(f_hash(i,i+k-1,1),f_hash(i,i+k-1,0));
            s.insert(tmp);
        }
        return s.size();
    }
    int main() 
    {
        scanf("%llu",&n);
        for(ull i=1;i<=n;i++)
            scanf("%llu",&a[i]);
        power[0]=1;
        for(ull i=1;i<=n;i++)
        {
            sum1[i]=sum1[i-1]*p+a[i];
            power[i]=power[i-1]*p;
        }
        for(ull i=n;i>=1;i--)
            sum2[i]=sum2[i+1]*p+a[i];
    //    for(ull i=1;i<=n;i++)
    //        printf("%llu %llu
    ",sum1[i],sum2[i]);
        ull maxx=0,cnt=0;
        for(ull i=1;i<=n;i++)
        {
            ull now=cal(i);
            if(now>maxx)
            {
                maxx=now;
                cnt=0;
            }
            if(maxx==now)
                ans[++cnt]=i;
        }
        printf("%llu %llu
    ",maxx,cnt);
        for(int i=1;i<=cnt;i++)
            printf("%llu ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    2017.10.12
    2017.10.25
    2017.10.24
    进度条06
    课堂练习(返回一个环状一维整数数组中最大子数组的和)
    团队项目成员和题目
    团队作业--四则运算网页版
    进度条04
    个人作业(最大子数组)
    进度条03
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11767000.html
Copyright © 2011-2022 走看看