Codeforces Round #566 (Div. 2)

题目链接:http://codeforces.com/contest/1182

A Filling Shapes

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int n;
	while(~scanf("%d",&n)){
		if(n&1){
			printf("0\n");
		}else{
			printf("%d\n",1<<(n/2));
		}
	}
	return 0;
}

B Plus from Picture

#include<bits/stdc++.h>
using namespace std;
const int maxn=510;

int n,m;
char mp[maxn][maxn];
int dx[9]={0,1,-1,0,0,-1,1,-1,1};
int dy[9]={0,0,0,1,-1,-1,1,1,-1};
inline bool ok(int x,int y)
{
	for(int i=0;i<9;i++){
		int xx=x+dx[i],yy=y+dy[i];
		if(xx<0||yy<0||xx>=n||yy>=m)
			return false;
		if(i>4&&mp[xx][yy]!='.') return false;
		if(i<=4&&mp[xx][yy]!='*') return false;
	}
	return true;
}
int main()
{
	while(~scanf("%d%d",&n,&m)){
		for(int i=0;i<n;i++){
			scanf("%s",mp[i]);
		}
		bool flag=0,tag=1;
		int x,y;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(ok(i,j)){
					if(flag){
						tag=0;break;
					}else{
						flag=1;x=i;y=j;
					}
					
				}
			}
			if(!tag) break;
		}
		if(!flag) tag=0; 
		if(tag){
			int i,j;
			i=x;
			while((i+1)<n&&mp[i+1][y]=='*') mp[i+1][y]='.',i++;
			i=x;
			while((i-1)>=0&&mp[i-1][y]=='*') mp[i-1][y]='.',i--;
			j=y;
			while((j+1)<m&&mp[x][j+1]=='*') mp[x][j+1]='.',j++;
			j=y;
			while((j-1)>=0&&mp[x][j-1]=='*') mp[x][j-1]='.',j--;
			mp[x][y]='.';
		}
		if(tag)
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(mp[i][j]=='*'){
					tag=0;break;
				}
			}
			if(!tag) break;
		}
		if(tag) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

C Beautiful Lyrics

题意:给n个单词,每个单词至少有1个元音字母,构造一个2行序列,每行由2个单词构成。(0<n<=1000000)
第1行的第1个单词和第2行的第1个单词的元音数相同;
第1行的第2个单词和第2行的第2个单词的元音数相同;
第1行的第2个单词和第2行的第2个单词的最后一个元音是相同的。
当时没注意到这个:Note that you cannot use a word more times than it is given to you

awsl
按元音数排序,再按单词最后一个元音排序,贪心构造。

#include<bits/stdc++.h>
using namespace std;
const int maxn=100010;

struct node{
	string s;
	int num;//
	int last;
}a[maxn],b[maxn];
bool vis[maxn];
char c[5]={'a','e','i','o','u'};
bool cmp(const node &x,const node &y)
{
	return x.num!=y.num? x.num<y.num:x.last<y.last;
}
string ans[maxn][2][2];

int main()
{
	int n,m;
	ios::sync_with_stdio(false);
	while(cin>>n){
		memset(vis,0,sizeof(vis));//
		string s;
		int num,last,len;
		for(int i=0;i<n;i++){
			cin>>s;
			len=s.length();
			num=0;//
			for(int j=0;j<len;j++){
				for(int k=0;k<5;k++){
					if(s[j]==c[k]){
						num++;
						last=k;
						break;
					}
				}
			}
			a[i].s=s;a[i].num=num;
			a[i].last=last;
		}
		sort(a,a+n,cmp);
//		for(int i=0;i<n;i++){
//			cout<<a[i].s<<" num: "<<a[i].num<<" last: "<<c[a[i].last]<<endl;
//		}
		int m1=0,m2=0,tmp;
		for(int i=0;i<n;i++){
			tmp=i;
			while((i+1)<n&&(a[i+1].num==a[tmp].num&&a[i+1].last==a[tmp].last))
				i++;
			m1+=i-tmp+1>>1;
		}
		for(int i=0;i<n;i++){
			tmp=i;
			while((i+1)<n&&(a[i+1].num==a[tmp].num))
				i++;
			m2+=i-tmp+1>>1;
		}
		int m=min(m1,m2/2);
		cout<<m<<endl;
		if(!m) continue;//
		int tot=0;
		for(int i=0;i<n;i++){
			if((i+1)<n&&a[i].num==a[i+1].num&&a[i].last==a[i+1].last){
				ans[tot][0][1]=a[i].s;ans[tot++][1][1]=a[i+1].s;
				vis[i]=vis[i+1]=1;
//				printf("id:%d - %d ",i,i+1);cout<<a[i].s<<" "<<a[i+1].s<<endl;
				if(tot==m) break;//
				i++;
			}
		}
		int n1=n;
		n=0;
		for(int i=0;i<n1;i++) if(!vis[i]) b[n++]=a[i];
		tot=0;
		for(int i=0;i<n;i++){
			if((i+1)<n&&b[i].num==b[i+1].num){
				ans[tot][0][0]=b[i].s;ans[tot][1][0]=b[i+1].s;
//				printf("idd:%d - %d ",i,i+1);cout<<b[i].s<<" "<<b[i+1].s<<endl;
				cout<<ans[tot][0][0]<<" "<<ans[tot][0][1]<<endl;
				cout<<ans[tot][1][0]<<" "<<ans[tot][1][1]<<endl;
				tot++;if(tot==m) break;
				i++;
			}
		}
	}
	return 0;
}

E Product Oriented Recurrence

f x = C 2 ∗ x − 6 ∗ f x − 1 ∗ f x − 2 ∗ f x − 3 f_{x}=C^{2*x-6}*f_{x-1}*f_{x-2}*f_{x-3} fx=C2x6fx1fx2fx3 for x &gt; = 4 x&gt;=4 x>=4 n , f 1 , f 2 , f 3 , c n, f1 ,f2,f3 ,c n,f1,f2,f3,c f n m o d ( 1 0 9 + 7 ) f_{n}mod(10_{9}+7) fnmod(109+7)
题解:矩阵快速幂,把 f 1 , f 2 , f 3 , c f1 ,f2,f3 ,c f1,f2,f3,c对应的指数都用矩阵快速幂求出,再用一次快速幂求得答案。
注意:在指数也需要取模,对于指数的取模,根据费马小定理,指数取模为 φ ( m o d ) = m o d − 1 ( 这 里 m o d 为 1 e 9 + 7 ) \varphi(mod)=mod-1(这里mod为1e9+7) φ(mod)=mod1mod1e9+7)
对于 f 1 , f 2 , f 3 f1 ,f2,f3 f1,f2,f3,其矩阵为
{ 1 1 0 1 0 1 1 0 0 } \left\{ \begin{matrix} 1 &amp; 1 &amp; 0\\ 1 &amp; 0 &amp; 1 \\ 1&amp;0 &amp; 0 \end{matrix} \right\} 111100010
f 1 , f 2 , f 3 f1 ,f2,f3 f1,f2,f3分别用(0,0,1),(0,1,0),(1,0,0)乘以该矩阵的(n-3)次方即可求其指数。
c则用
{ 1 1 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0 − 6 0 0 2 1 } \left\{ \begin{matrix} 1 &amp; 1 &amp; 0 &amp; 0 &amp; 0\\ 1 &amp; 0 &amp; 1 &amp; 0 &amp; 0\\ 1&amp;0 &amp; 0 &amp; 0 &amp; 0\\ 1&amp;0 &amp; 0 &amp; 1 &amp; 0\\ -6&amp;0 &amp; 0 &amp; 2 &amp; 1\\ \end{matrix} \right\} 1111610000010000001200001
用(0,0,0,8,1)乘以该矩阵的(n-3)次方即可求其指数。
最后答案就是 a n s = f 1 p 1 ∗ f 2 p 2 ∗ f 3 p 3 ∗ c p 4 ans=f1^{p1}*f2^{p2}*f3^{p3}*c^{p4} ans=f1p1f2p2f3p3cp4

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod=1e9+7;
const int mod2=1e9+6;//for exponent

ll n;
struct Matrix{
	int a[5][5];
	int x;
	void clr(){
		memset(a,0,sizeof(a));
	}
	Matrix operator *(const Matrix &M){
		Matrix tmp;
		tmp.clr();
		for(int i=0;i<5;i++)
			for(int k=0;k<5;k++)
				for(int j=0;j<5;j++)
					tmp.a[i][k]=(tmp.a[i][k]+1LL*a[i][j]*M.a[j][k]%mod2)%mod2;
		return tmp;
	}
	void print()
	{
		printf("------------\n");
		for(int i=0;i<5;i++){
			for(int j=0;j<5;j++){
				printf("%d ",a[i][j]);
			}
			printf("\n");
		}
	}
}E,M,Ans;
Matrix qpow(Matrix M,ll p)
{
	Matrix E;
	E.clr();
	for(int i=0;i<5;i++) E.a[i][i]=1;
	while(p){
		if(p&1) E=E*M;
		M=M*M;
		p>>=1;
	}
	return E;
}
int cal(int x)//inline 
{
	E.clr();
	E.a[0][x]=1;
	Ans=E*qpow(M,n-3);
	return Ans.a[0][0];
}
int qp(int a,int p)//inline 
{
	int ans=1;
	while(p){
		if(p&1)
			ans=1LL*ans*a%mod;
		a=1LL*a*a%mod;
		p>>=1;
	}
	return ans;
}
int main()
{
	int f1,f2,f3,c;
	while(~scanf("%I64d%d%d%d%d",&n,&f1,&f2,&f3,&c)){
		M.clr();
		M.a[0][0]=M.a[1][0]=M.a[2][0]=1;
		M.a[0][1]=M.a[1][2]=1;
		int p1=cal(2);
		int p2=cal(1);
		int p3=cal(0);
		M.a[3][0]=M.a[3][3]=M.a[4][4]=1;
		M.a[4][0]=-6;
		M.a[4][3]=2;
		E.clr();
		E.a[0][3]=8;E.a[0][4]=1;
		
		Ans=E*qpow(M,n-3);
		int p4=Ans.a[0][0];
		int ans=1LL*qp(c,p4)*qp(f1,p1)%mod*qp(f2,p2)%mod*qp(f3,p3)%mod;
		printf("%d\n",ans);
		
	}
	return 0;
}
// 4 1 2 5 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值