[2016-2017 ACM-ICPC, South Pacific Regional Contest (SPPC 16)]C Crazy Rotations
题目大意:给你一个由'R' 'B' 'Y'组成的长度为n的字符串S,操作k表示将字符串的最后k位移到字符串的开头。定义一个操作k的craziness为原串进行操作k之后,形成的字符串与原串相同位置不同字符的位置数目。要求你构造一个由操作序列,为1...n-1的一个全排列,使得第i位上的操作数目递增。
题解:构造三个函数\[R(x)=a_0+a_1x^1+a_2x^2+...+a_{n-1}x^{n-1}\]\[B(x)=b_0+b_1x^1+b_2x^2+...+b_{n-1}x^{n-1}\]\[Y(x)=c_0+c_1x^1+c_2x^2+...+c_{n-1}x^{n-1}\]
其中\(S_i='R'\)时\(a_i=1\),\(S_i='B'\)时\(b_i=1\),\(S_i='Y'\)时\(c_i=1\),其余各项为0。
\(A(x)*A^-1(x)\)
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
const double pi=M_PI;
const int DEBUG=1;
struct Complex
{
double r,i;
Complex (double _r=0,double _i=0):r(_r),i(_i){}
friend Complex operator + (const Complex &a,const Complex &b);
friend Complex operator - (const Complex &a,const Complex &b);
friend Complex operator * (const Complex &a,const Complex &b);
};
Complex operator + (const Complex &a,const Complex &b) {return Complex(a.r+b.r,a.i+b.i);}
Complex operator - (const Complex &a,const Complex &b) {return Complex(a.r-b.r,a.i-b.i);}
Complex operator * (const Complex &a,const Complex &b) {return Complex(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);}
int rev[maxn<<2];
int N;
void FFT(Complex *arr,int ctr)
{
for (int i=0;i<N;i++) if (i<rev[i]) swap(arr[i],arr[rev[i]]);
for (int i=1;i<N;i<<=1)
{
Complex wn(cos(pi/i),ctr*sin(pi/i));
for (int j=0;j<N;j+=(i<<1))
{
Complex w(1,0);
for (int k=0;k<i;k++,w=w*wn)
{
Complex x=arr[j+k],y=w*arr[j+k+i];
arr[j+k]=x+y;arr[j+k+i]=x-y;
}
}
}
if (ctr==-1) for (int i=0;i<N;i++) arr[i].r/=N;
}
char ch[maxn];
Complex a[maxn<<2],a0[maxn<<2],b[maxn<<2],b0[maxn<<2],c[maxn<<2],c0[maxn<<2];
long long cnt[maxn];
int Rank[maxn];
int n,p;
bool cmp(const int &a,const int &b) {return cnt[a]>cnt[b];}
int main()
{
scanf("%d%d\n",&n,&p);
scanf("%s",ch);
for (int i=0;i<n;i++)
if (ch[i]=='R') a[i].r=1;
else if (ch[i]=='B') b[i].r=1;
else if (ch[i]=='Y') c[i].r=1;
for (int i=0;i<n;i++) a0[i]=a[n-i-1],b0[i]=b[n-i-1],c0[i]=c[n-i-1];
N=1;
while (N<(n<<1)) N<<=1;
for (int i=0;i<N;i++) rev[i]=(rev[i>>1]>>1)|((i&1)*(N>>1));
FFT(a,1);FFT(a0,1);
FFT(b,1);FFT(b0,1);
FFT(c,1);FFT(c0,1);
for (int i=0;i<N;i++) a[i]=a[i]*a0[i],b[i]=b[i]*b0[i],c[i]=c[i]*c0[i];
FFT(a,-1);
FFT(b,-1);
FFT(c,-1);
for (int i=1;i<n;i++) cnt[i]=(int)(a[n-1+i].r+a[i-1].r+0.1)+(int)(b[n-1+i].r+b[i-1].r+0.1)+(int)(c[n-1+i].r+c[i-1].r+0.1);
for (int i=1;i<n;i++) Rank[i]=i;
sort(Rank+1,Rank+n,cmp);
for (int i=1;i<n;i++)
{
int r=i,minv=Rank[i];
while (r<n-1 && cnt[Rank[i]]==cnt[Rank[r+1]]) minv=min(minv,Rank[++r]);
if (r>=p) {printf("%d\n",minv);return 0;}
i=r;
}
}
评论 (0)