首先……我要大喊三声flaze煞笔
T2……当时刚写完不知哪儿抽了手一抖一个shift+del删源码,解锁成就【mdzz】,然后重写的时候,果断脑残取模优化GG
嗯……T3莫名其妙WA了一年,这种瘠薄题拿头来WA啊【跪地】……最后发现……调试的时候数组开小了,然后……タマダ,没删调,GGGGGG
……
T1:煞笔模拟题,没什么好说的
T2:
题面:……求 fib(fib(n)) % (1e9+7) 的值,n是1e100。
思路:显然找规律,于是发现 fib(i)%(1e9+7) 的 i 的循环节是 2e9+16 , 于是内层fib相当于是%(2e9+16) 的,继续暴力找循环节,发现这货的循环节是329616 【把模数写出来就是为了破坏将来如果会复习的flaze的游戏体验喵嘿嘿你回来打我啊23333】嗯,找到循环节之后矩阵快速幂一下,完了
代码:
#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std; int T; long long n;
const long long MOD3 = 329616;
char read_s[105];
inline long long read(){
scanf("%s",read_s);
char *s=read_s;
long long f=1,rtn=0;
if(*s=='-') f=-1,++s;
for(;*s;++s){
rtn=rtn*10+*s-'0';
if(rtn>=MOD3) rtn-=MOD3;
}
return f*rtn;
}
struct Matrix{
int x,y;
int mod;
int d[2][2];
Matrix():x(0),y(0){memset(d,0,sizeof d);}
Matrix(int x):x(x),y(x){memset(d,0,sizeof d);for(int i=0;i<x;++i) d[i][i]=1;}
Matrix(int x,int y):x(x),y(y){memset(d,0,sizeof d);}
Matrix operator * (const Matrix ano){
Matrix RTN(x,ano.y);
RTN.mod=this->mod;
for(int i=0;i<x;++i)
for(int j=0;j<y;++j)
for(int k=0;k<ano.y;++k)
RTN.d[i][k]=(RTN.d[i][k]+1ll*d[i][j]*ano.d[j][k]%mod)%mod;
return RTN;
}
Matrix pow(long long c){
if(!c){
Matrix RTN=Matrix(2,2);
RTN.mod=this->mod;
return RTN;
}
--c;
Matrix RTN(x),TMP=*this;
RTN.mod=this->mod;
for(;c;c>>=1,TMP=TMP*TMP)
if(c&1)
RTN=RTN*TMP;
return RTN;
}
}ori1,ori2,trans1,trans2;
void init(){
ori1=Matrix(2,1);
ori1.mod=2000000016;
ori2=Matrix(2,1);
ori2.mod=MOD;
trans1=trans2=Matrix(2,2);
ori1.d[0][0]=ori2.d[0][0]=1;
ori1.d[1][0]=ori2.d[1][0]=0;
trans1.d[0][0]=trans1.d[0][1]=1;
trans2.d[0][0]=trans2.d[0][1]=1;
trans1.d[1][0]=trans2.d[1][0]=1;
trans1.mod=2000000016;
trans2.mod=MOD;
}
int fib(long long i){
Matrix TMP=trans1.pow(i)*ori1;
i=(long long)TMP.d[0][0];
TMP=trans2.pow(i)*ori2;
int k=TMP.d[0][0];
return k;
}
int main(){
freopen("na.in","r",stdin);
freopen("na.out","w",stdout);
init();
scanf("%d",&T);
while(T--){
n=read();
printf("%d\n",fib(n));
}
return 0;
}
T3:…………我cnmb打的是友军x
题面:
你现在希望组建一支足球队,一支足球队一般来说由11人组成。 这11人有四
种不同的职业:守门员、后卫、中锋、前锋组成。你在组队的时候必须满足以下
规则:
1、 足球队恰好由11人组成。
2、 11人中恰好有一名守门员, 3-5 名后卫, 2-5 名中锋, 1-3 名前锋。
3、 你需要从这11人中选出一名队长。
4、 你这个足球队的价值是11人的价值之和再加上队长的价值,也就是说
队长的价值会被计算两次。
5、 你这个足球队的花费是11人的花费之和,你的花费之和不能超过给定
的上限。
现在告诉你球员的总数,每个球员的职业、价值、花费,以及花费的上限,
你希望在满足要求的情况下,达到以下目标:
1、 最大化队伍的价值。
2、 在最大化队伍的价值的情况下,最小化队伍的花费。
3、 在满足以上两个要求的情况下,有多少种选择球员的方案。如果有两
种方案它们的区别仅仅是队长不一样,那么这两种方案应该被认为是一样的
思路:排序之后sb魔改背包,f[a][b][c][d][cc]表示四种分别有几个,花费为cc的最大value,方案数,队长的值(显然应该是当前的最大值最优)
代码:
#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXM 1005
#define MOD 1000000000
#define INF 0x3f3f3f3f
using namespace std; int n,lim;
struct t2{
int value,cost,type;
t2():value(0),cost(0),type(0){}
t2(int value,int cost,int type):value(value),cost(cost),type(type){}
bool operator < (const t2 &ano)const{
return value==ano.value? cost>ano.cost: value<ano.value;
}
}p[MAXM];
struct t1{
int value,cnt,mx;
t1():value(0),cnt(0),mx(0){}
t1(int value,int cnt,int mx):value(value),cnt(cnt),mx(mx){}
}f[2][6][6][4][MAXM];
int llimit[5]={0,1,3,2,1};
int rlimit[5]={0,1,5,5,3};
char read_s[20];
int read_v,read_c;
inline void init(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%s%d%d",read_s,&read_v,&read_c);
if(read_s[0]=='G') p[i]=t2(read_v,read_c,1);
if(read_s[0]=='D') p[i]=t2(read_v,read_c,2);
if(read_s[0]=='M') p[i]=t2(read_v,read_c,3);
if(read_s[0]=='F') p[i]=t2(read_v,read_c,4);
}
scanf("%d",&lim);
sort(p+1,p+n+1);
}
inline void make_F(){
f[0][0][0][0][0]=t1(0,1,-1);
for(int i=1;i<=n;++i)
for(int a=rlimit[1]-(p[i].type==1);~a;--a)
for(int b=rlimit[2]-(p[i].type==2);~b;--b)
for(int c=rlimit[3]-(p[i].type==3);~c;--c)
for(int d=rlimit[4]-(p[i].type==4);~d;--d){
if(a+b+c+d>=11) continue;
for(int cc=lim-p[i].cost;~cc;--cc){
t1 tmp=f[a][b][c][d][cc],
&aim=f[a+(p[i].type==1)][b+(p[i].type==2)]
[c+(p[i].type==3)][d+(p[i].type==4)]
[cc+p[i].cost];
if(!tmp.cnt) continue;
int kk = tmp.value + p[i].value;
if(kk > aim.value){
aim.value = kk;
aim.cnt = tmp.cnt;
aim.mx = p[i].value;
}
else{
if(kk == aim.value){
if(p[i].value > aim.mx)
aim.cnt = tmp.cnt , aim.mx = p[i].value;
else{
if(p[i].value == aim.mx)
aim.cnt += tmp.cnt;
}
}
}
if(aim.cnt > MOD) aim.cnt=MOD;
}
}
}
inline void get_ans(){
int ans_value=0,ans_cost=INF,ans_cnt=0;
for(int a=llimit[1];a<=rlimit[1];++a)
for(int b=llimit[2];b<=rlimit[2];++b)
for(int c=llimit[3];c<=rlimit[3];++c)
for(int d=llimit[4];d<=rlimit[4];++d){
if((a+b+c+d)^11) continue;
for(int cc=0;cc<=lim;++cc){
t1 now=f[a][b][c][d][cc];
if(!now.cnt) continue;
if(now.value + now.mx > ans_value){
ans_value = now.value + now.mx;
ans_cost = cc;
ans_cnt = now.cnt;
}
else if(now.value + now.mx == ans_value){
if(cc == ans_cost) ans_cnt += now.cnt;
else if(cc < ans_cost)
ans_cost = cc , ans_cnt = now.cnt;
}
if( ans_cnt>MOD ) ans_cnt=MOD;
}
}
printf("%d %d %d",ans_value,ans_cost,ans_cnt);
}
int main(){
init();
make_F();
get_ans();
return 0;
}