其他分享
首页 > 其他分享> > 4.5省选练习

4.5省选练习

作者:互联网

\(T1\)

\(emm,\)爆搜\(?\)好久没见过搜索题了...

一样的就跳,不一样的就改\(TAT\)

#include<bits/stdc++.h>
#define MAXM 1000010
#define MAXN 210
using namespace std;
char *a,*b;
int len[MAXN];
string s[MAXN];
int ans[10],ans1,n;
void work(int i,int j,int leni,int lenj,int cnt)
{
    if(cnt+abs(leni-i+j-lenj)>=ans1)return;
    while(i<leni&&j<lenj)
    {
        if(a[i]!=b[j])
        {
            work(i+1,j+1,leni,lenj,cnt+1);
            work(i+1,j,leni,lenj,cnt+1);
            work(i,j+1,leni,lenj,cnt+1);
            return;
        }
        i++;j++;
    }
    if(i==leni)ans1=min(ans1,cnt+lenj-j);
    else ans1=min(ans1,cnt+leni-i);
}

int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        cin>>s[i];
        len[i]=strlen(s[i].c_str());
    }
    for(int i=0;i<n;i++)
    {
        a=(char*)s[i].c_str();
        for(int j=i+1;j<n;j++)
        {
            b=(char*)s[j].c_str();
            ans1=9;
            work(0,0,len[i],len[j],0);
            ans[ans1]++;
        }
    }
    for(int i=1;i<8;i++)printf("%d ",ans[i]);
    printf("%d\n",ans[8]);
    return 0;
}

\(T2\)

感觉和特征多项式有点关系\(?\)

确实有点关系,这种题都能推通项公式吧,利用特征根求

\(A_n=p\times 3^n+q\times(-1)^n\)

推导一下

\(f[x]=a\times f[x-1]+b\times f[x-2]\)

\(f[x]-t\times f[x-1]=k\times(f[x-1]-t\times f[x-2])\)

\(f[x]=(k+t)\times f[x-1]-k\times t\times f[x-2]\)

最后

\(a_n-\lambda a_{n-1}=\mu(a_{n-1}-\lambda a_{n-2})\)

\(\left\{\begin{matrix} \lambda = 3\\ \mu = -1\end{matrix}\right.\text{}\left\{\begin{matrix} \lambda = -1\\ \mu = 3 \end{matrix}\right.\)

最后带回得到

\(4f(n-1)=(3^{n-1}+(-1)^{n-2})(f(2)-f(1))\)

最后得到

\(A_n=p\times 3^n+q\times(-1)^n\)

我们只需要对两个分别计算贡献

我们对于每一个位置扔一个\((1+3^{a_i}x)\)最后求出来\(x^k\)是恰好全\(k\)个的\(3^z\)和

直接分治\(FFT\)即可

#include<bits/stdc++.h>
#define MAXN 524298
using namespace std;
const int p=99991;
const long double pi=acos(-1);
int n,K,a[MAXN];
struct node
{
	long double x,y;
	node(long double xx=0,long double yy=0){x=xx,y=yy;}
	node operator - (const node &B){return node(x-B.x,y-B.y);}
	node operator + (const node &B){return node(x+B.x,y+B.y);}
	node operator * (const node &B){return node(x*B.x-y*B.y,x*B.y+y*B.x);}
	node operator * (const long double &B) {return node(x*B,y*B);}
}A[MAXN],B[MAXN],C[MAXN],w[MAXN];
int rev[MAXN];
void FFT(node *A,int n,int op)
{
	for(int i=1;i<n;i++)
	{
		if(rev[i]>i) swap(A[i],A[rev[i]]);
	}
	node x,y;
	for(int k=2;k<=n;k<<=1)
	{
		for(int i=0;i<n;i+=k)
		{
			for(int j=0;j<(k>>1);j++)
			{
				x=A[i+j],y=w[n/k*j]*A[i+j+(k>>1)];
				A[i+j]=x+y;
				A[i+j+(k>>1)]=x-y;
			}
		}
	}
	if(op==-1)
	{
		long double tmp=1.0/n;
		for(int i=0;i<n;i++) A[i]=A[i]*tmp;
	}
}
int ttmp[MAXN];
void wor(int *a,int *b,int *c,int n1,int n2)
{
	int m=n1+n2-1;
	int t,l;
	if(m<=500)
	{
	    memset(ttmp,0,sizeof(int)*(m+2));
	    for(int i=0;i<n1;i++)
	    {
	        for(int j=0;j<n2;j++)
	        {
	            ttmp[i+j]+=1ll*a[i]*b[j]%p;
	            if(ttmp[i+j]>=p) ttmp[i+j]-=p;
	        }
	    }
	    for(int i=0;i<m;i++) c[i]=ttmp[i];
	    return ;
	}
	for(t=1,l=0;t<m;t<<=1,l++);l--;
	for(int i=1;i<t;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<l);
	for(int i=0;i<n1;i++) A[i]=node(a[i],0);
	for(int i=0;i<n2;i++) B[i]=node(b[i],0);
	for (int i=0;i<=t;i++) w[i]=node(cos(pi*2/t*i),sin(pi*2/t*i));
	for(int i=n1;i<t;i++) A[i]=node();
	for(int i=n2;i<t;i++) B[i]=node();
	FFT(A,t,0);
	FFT(B,t,0);
	for(int i=0;i<t;i++) C[i]=A[i]*B[i];
    for (int i=0;i<=t;i++) w[i]=node(cos(pi*2/t*i),sin(-1.0*pi*2/t*i));
	FFT(C,t,-1);
	for(int i=0;i<m;i++) c[i]=(long long)(C[i].x+0.5)%p;
}
int my_pow(int x,int z)
{
	int ans=1;
	while(z)
	{
		if(z&1)
		{
			ans=1ll*ans*x%p;
		}
		x=1ll*x*x%p;
		z>>=1;
	}
	return ans;
}
int an[20][MAXN];
inline void work(int l,int r,int dep)
{
	if(l==r)
	{
		an[dep][0]=1;
		an[dep][1]=my_pow(3,a[l]);
		return ;
	}
	int mid=(l+r)>>1;
	work(l,mid,dep+1);
	for(int i=0;i<=(mid-l+1);i++) an[dep][i]=an[dep+1][i];
	work(mid+1,r,dep+1);
	wor(an[dep],an[dep+1],an[dep],mid-l+2,r-mid+1);
}
int jc[MAXN],ni[MAXN];
int get_c(int a,int b)
{
	if(b>a)return 0;
	return 1ll*jc[a]*ni[b]%p*ni[a-b]%p;
}
int js[5];
int work2()
{
	jc[0]=ni[0]=1;
	for(int i=1;i<p;i++) jc[i]=1ll*jc[i-1]*i%p;
	ni[p-1]=my_pow(jc[p-1],p-2);
	for(int i=p-2;i;i--) ni[i]=1ll*ni[i+1]*(i+1)%p;
	for(int i=1;i<=n;i++) js[a[i]&1]++;
	int ans=0;
	for(int i=0;i<=K;i++) 
	{
		if(i&1) ans+=p-1ll*get_c(js[1],i)*get_c(js[0],K-i)%p;
		else ans+=1ll*get_c(js[1],i)*get_c(js[0],K-i)%p;
		ans%=p;
	}
	return ans;
}
int f0,f1;
int main()
{
	scanf("%d%d",&n,&K);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		a[i]%=19998;
	}
	scanf("%d%d",&f0,&f1);
	work(1,n,0);
	int tmp1,tmp2;
	tmp1=1ll*(f0+f1)*my_pow(4,p-2)%p;
	tmp2=1ll*(3*f0-f1+p)*my_pow(4,p-2)%p;
	printf("%lld\n",(1ll*an[0][K]*tmp1%p+1ll*tmp2*work2()%p)%p);
	return 0;
}

\(T3\)

原题

标签:4.5,node,return,省选,练习,times,int,MAXN,const
来源: https://www.cnblogs.com/Eternal-Battle/p/16103017.html