zoukankan      html  css  js  c++  java
  • E. Rusty String

    E. Rusty String
    time limit per test
    3 seconds
    memory limit per test
    512 megabytes
    input
    standard input
    output
    standard output

    Grigory loves strings. Recently he found a metal strip on a loft. The strip had length n and consisted of letters "V" and "K". Unfortunately, rust has eaten some of the letters so that it's now impossible to understand which letter was written.

    Grigory couldn't understand for a long time what these letters remind him of, so he became interested in the following question: if we put a letter "V" or "K" on each unreadable position, which values can the period of the resulting string be equal to?

    A period of a string is such an integer d from 1 to the length of the string that if we put the string shifted by d positions to the right on itself, then all overlapping letters coincide. For example, 3 and 5 are periods of "VKKVK".

    Input

    There are several (at least one) test cases in the input. The first line contains single integer — the number of test cases.

    There is an empty line before each test case. Each test case is described in two lines: the first line contains single integer n(1 ≤ n ≤ 5·105) — the length of the string, the second line contains the string of length n, consisting of letters "V", "K" and characters "?". The latter means the letter on its position is unreadable.

    It is guaranteed that the sum of lengths among all test cases doesn't exceed 5·105.

    For hacks you can only use tests with one test case.

    Output

    For each test case print two lines. In the first line print the number of possible periods after we replace each unreadable letter with "V" or "K". In the next line print all these values in increasing order.

    Example
    input
    3
     
    5
    V??VK
     
    6
    ??????
     
    4
    ?VK?
    output
    2
    3 5
    6
    1 2 3 4 5 6
    3
    2 3 4
    Note

    In the first test case from example we can obtain, for example, "VKKVK", which has periods 3 and 5.

    In the second test case we can obtain "VVVVVV" which has all periods from 1 to 6.

    In the third test case string "KVKV" has periods 2 and 4, and string "KVKK" has periods 3 and 4.

    分析:对于一个可能的值x,当且仅当不存在si != sj , si != '?' , sj != '?' , i%x = j%x这样的情况。

       所以首先计算距离差为x且i,j满足上述不符合条件的情形;

       距离差一定集合的和,很容易想到fft;

       最后若y%x == 0,y不成立,显然x也不成立;

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <bitset>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cassert>
    #include <ctime>
    #define rep(i,m,n) for(i=m;i<=(int)n;i++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define sys system("pause")
    #define ls rt<<1
    #define rs rt<<1|1
    #define all(x) x.begin(),x.end()
    const int maxn=2e6+10;
    const int N=5e2+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;}
    ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=qmul(f,p,mo)%mo;p=qmul(p,p,mo)%mo;q>>=1;}return f;}
    int n,m,k,t;
    ll ret[maxn],ans[maxn];
    char a[maxn];
    struct Complex
    {
        double r,i;
        Complex(double _r,double _i):r(_r),i(_i){}
        Complex(){}
        Complex operator +(const Complex &b)
        {
            return Complex(r+b.r,i+b.i);
        }
        Complex operator -(const Complex &b)
        {
            return Complex(r-b.r,i-b.i);
        }
        Complex operator *(const Complex &b)
        {
            return Complex(r*b.r-i*b.i,r*b.i+i*b.r);
        }
    }x[maxn],y[maxn];
    void change(Complex y[],int len)
    {
        int i,j,k;
        for(i = 1, j = len/2;i < len-1;i++)
        {
            if(i < j)swap(y[i],y[j]);
            k = len/2;
            while( j >= k)
            {
                j -= k;
                k /= 2;
            }
            if(j < k)j += k;
        }
    }
    void fft(Complex y[],int len,int on)
    {
        change(y,len);
        for(int h = 2;h <= len;h <<= 1)
        {
            Complex wn(cos(-on*2*pi/h),sin(-on*2*pi/h));
            for(int j = 0;j < len;j += h)
            {
                Complex w(1,0);
                for(int k = j;k < j+h/2;k++)
                {
                    Complex u = y[k];
                    Complex t = w*y[k+h/2];
                    y[k] = u+t;
                    y[k+h/2] = u-t;
                    w = w*wn;
                }
            }
        }
        if(on == -1)
            for(int i = 0;i < len;i++)
                y[i].r /= len;
    }
    int main()
    {
        int i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%s",&n,a);
            for(i=0;i<n;i++)
            {
                x[i]=Complex(a[i]=='V',0);
                y[n-1-i]=Complex(a[i]=='K',0);
            }
            int len=1;
            while(len<n*2)len=len*2;
            rep(i,n,len-1)x[i]=y[i]=Complex(0,0);
            fft(x,len,1);
            fft(y,len,1);
            rep(i,0,len-1)x[i]=x[i]*y[i];
            fft(x,len,-1);
            rep(i,0,2*n-1)ans[i]=round(x[i].r);
            rep(i,0,n)ret[i]=0;
            rep(i,0,2*n-1)ret[abs(i-n+1)]|=(ans[i]!=0);
            rep(i,1,n)
            {
                for(j=i;j<=n;j+=i)
                {
                    ret[i]|=ret[j];
                }
            }
            int c=0;
            rep(i,1,n)if(!ret[i])c++;
            printf("%d
    ",c);
            rep(i,1,n)if(!ret[i])printf("%d ",i);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Andrew Ng机器学习课程12
    Andrew Ng机器学习课程12
    排序算法十一:计数排序
    排序算法十一:计数排序
    排序算法十:桶排序
    排序算法十:桶排序
    基于MSP430F2618的程控电压源
    基于MSP430F2618的程控电压源
    Andrew Ng机器学习课程11之使用machine learning的建议
    Andrew Ng机器学习课程11之使用machine learning的建议
  • 原文地址:https://www.cnblogs.com/dyzll/p/7198042.html
Copyright © 2011-2022 走看看