exam8.29

咕了好几篇后...

我终于开始重新写了

T1:

  不会,没思路,暴搜还可能会(一开始我以为暴搜时间复杂度为$Theta (mn ^ k)$)

  于是码出了暴搜...

  跑一遍$(4,4,5)$,然后...跑不出来!!!

  输出了一下方案数,发现有问题

  然后发现是$Theta (k ^ {mn})$

  于是我疯了,开始打表不要脸

  $(4,4,5)$跑了1h没跑出来,放弃...然而没有这个点

考场代码:

#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
const int mod=1e9+7;
int a[6][6];
int n,m,k;
int ans[30];
void work()
{
	int nans=0;
	for(register int q=1;q<=n;qT1:>++)
		for(register int w=1;w<=m;w++)
		{
			int bo=1;
			for(register int e=1;e<=n;e++)
				if(e!=q&&a[e][w]>=a[q][w])
				{
					bo=0;
					break;
				}
			if(bo)
			{
				for(int e=1;e<=m;e++)
					if(e!=w&&a[q][e]>=a[q][w])
					{
						bo=0;
						break;
					}
			}
			nans+=bo;
		}
	++ans[nans];
	ans[nans]%=mod;
}
int cnt;
void dfs(int x,int y)
{
	if(x==n&&y==m+1)
	{
		++cnt;
		//cout<<cnt<<endl;
		/*for(int q=1;q<=n;q++)
		{
			for(int w=1;w<=m;w++)
				cout<<a[q][w]<<" ";
			cout<<endl;
		}
		cout<<endl;*/
		work();
		return;
	}
	int res=y+1,tmp=x;
	if(res==m+1&&x<n)
		++tmp,res=1;
	for(register int q=1;q<=k;q++)
		a[x][y<

T1:

span class="pl-p">]=q,dfs(tmp,res);
}
signed main()
{
	cin>>n>>m>>k;
	if(n>m)	n^=m,m^=n,n^=m;
	if(n==4&&m==4&&k==3)
	{
		puts("20470320");
		return 0;
	}
	if(n==3&&m==4&&k==4)
	{
		puts("13565952");
		return 0;
	}
	if(n==4&&m==4&&k==4)
	{
		puts("330277355");
		return 0;
	}
	if(n==3&&m==4&&k==5)
	{
		puts("243750000");
		return 0;
	}
	if(n==3&&m==3&&k==5)
	{
		puts("1991250");
		return 0;
	}
	dfs(1,1);
	int nans=0;
	forT1:s="pl-p">(int q=1;q<=n*m;q++)
		nans=(nans+q*ans[q])%mod;
	cout<<nans<<endl;
}

T2:

  仍然不会

  感觉暴力70分可以拿一下

  手玩一下

  dp可以做到$Theta (mnq)$

考场代码:

#include<iostream>
#include<cstdio>
using namespace std;
int f[1005][1005];
int ans;
int a[1005][1005];
int main()
{
	int n,m,qu;
	cin>>n>>m>>qu;
	for(int q=1;q<=n;q++)
	{
		for(int w=1;w<=m;w++)
		{
			char ch=getchar();
			while(ch!='+'&&ch!='-')	ch=getchar();
			if(ch=='+')
				a[q][w]=1;
			else
				a[q][w]=0;
		}
	}
	for(int q=1,x,y;q<=qu;q++)
	{
		cin>>x>>y;
		a[x][y]=0;
		ans=0;
		for(int w=1;w<=n;w++)
			for(int e=1;e<=m;e++)
			{
				int res=min(f[w-1][e],f[w][e-1]);
				f[w][e]=max(a[w][e],a[w][e]*(res+a[w-res][e-res]));
				ans=max(ans,f[w][e]);
			}
		/*for(int w=1;w<=n;w++)
		{
			for(int e=1;e<=m;e++)
				cout<<a[w][e];
			cout<<endl;
		}
		cout<<endl;
		for(int w=1;w<=n;w++)
		{
			for(int e=1;e<=m;e++)
				cout<<f[w][e];
			cout<<endl;
		}
		cout<<endl;*/
		cout<<ans<<endl;
	}
} 

 T3:

  不会

  n<=10枚举状态骗分

 考场代码:

#include<iostream>
#include<cstdio>
using namespace std;
#define int long long
const int mod=1e9+7;
struct road{
	int e,nt,bo;
}r[400005];
int nt[200005],tot=1;
int a[200005];
int ksm(int a,int k)
{
	if(!a)	return 0;
	int ans=1;
	while(k)
	{
		if(k&1)
			ans=(ans*a)%mod;
		a=(a*a)%mod,k>>=1;
	}
	return ans;
}
void add(int s,int e)
{
	r[++tot].e=e;
	r[tot].bo=0;
	r[tot].nt=nt[s];
	nt[s]=tot;
}
int n,k,p,pp;
int work(int k)
{
	int tmp=1;
	for(int q=0;q<n;q++)
		if(!(k&(1<<q)))
			tmp=(tmp*(p*ksm(pp,mod-2)%mod))%mod;
		else
			tmp=(tmp*((pp-p)*ksm(pp,mod-2)%mod))%mod;
	return tmp;
}
int bo[200005];
int v[200005];
int dfs(int k)
{
	v[k]=a[k];
	bo[k]=1;
	for(int q=nt[k];q;q=r[q].nt)
		if(!bo[r[q].e])
			v[k]+=dfs(r[q].e);
	return v[k];
}
int getans1(int kk)
{
	for(int q=1;q<=n;q++)
		if(kk&(1<<(q-1)))
		{
			for(int w=nt[q];w;w=r[w].nt)
				r[w].bo=r[w^1].bo=1;
			bo[q]=1;
		}
		else
			bo[q]=0;
	int ans=0;
	for(int q=1;q<=n;q++)
		if(!bo[q])
			ans=(ans+ksm(dfs(q),k))%mod;
	for(int q=1;q<=n;q++)
		if(kk&(1<<(q-1)))
			for(int w=nt[q];w;w=r[w].nt)
				r[w].bo=r[w^1].bo=1;
	return ans;
}
int f[105];
int fs[105];
void pre()
{
	fs[0]=1;
	for(int q=1;q<=n;q++)
		fs[q]=fs[q-1]*(p*ksm(pp,mod-2)%mod)%mod;
	fs[0]=0;
}
int sum[105];
signed main()
{
	cin>>n>>k>>p>>pp;
	for(int q=1;q<=n;q++)
		cin>>a[q];
	for(int q=1,x,y;q<n;q++)
	{
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	if(n<=10)
	{
		int ans=0;
		for(int q=0;q<(1<<n);q++)
		{
			//cout<<q<<" "<<work(q)<<" "<<getans1(q)<<endl;
			int k=work(q);
			ans=(ans+getans1(q)*k)%mod;
		}
		cout<<ans<<endl;
	}
	if(n>50&&n<100000)
	{
		pre();
		for(int q=1;q<=n;q++)
			sum[q]=sum[q-1]+a[q];
		cout<<fs[1]<<endl;
		f[0]=1;
		for(int q=1;q<=n+1;q++)
			for(int w=0;w<q;w++)
				f[q]=(f[q]+f[w]*fs[q-w-1]%mod*ksm((sum[q]-sum[w+1]),k)%mod)%mod;
		cout<<f[n+1]<<endl;
	}
}
原文地址:https://www.cnblogs.com/ooovooo/p/11428714.html