题目链接: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=C2∗x−6∗fx−1∗fx−2∗fx−3 for
x
>
=
4
x>=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)=mod−1(这里mod为1e9+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 & 1 & 0\\ 1 & 0 & 1 \\ 1&0 & 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 & 1 & 0 & 0 & 0\\ 1 & 0 & 1 & 0 & 0\\ 1&0 & 0 & 0 & 0\\ 1&0 & 0 & 1 & 0\\ -6&0 & 0 & 2 & 1\\ \end{matrix} \right\}
⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧1111−610000010000001200001⎭⎪⎪⎪⎪⎬⎪⎪⎪⎪⎫
用(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=f1p1∗f2p2∗f3p3∗cp4
#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