Wolfycz的娛樂賽 From Luogu 解題報告

比賽鏈接


洛谷 5135 painting

分析

可以發現對於opt=1opt=1時,答案爲C(n,m)C(n,m),對於opt=0opt=0時,可以認爲是不降序列,那麼使它變成遞增序列,取值變成了[1n+m][1\sim n+m],答案爲C(n+m1,m)C(n+m-1,m),所以就是這樣的,這是我比賽唯一切掉的QaQ


代碼

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long ll;
const ll mod=1000000007ll;
const int N=1000000; ll inv[N];
inline ll iut(){
	rr ll ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
	return ans;
}
inline ll ksm(ll x,ll y){
	rr ll ans=1;
	for (;y;y>>=1,(x*=x)%=mod)
	if (y&1) (ans*=x)%=mod;
	return ans;
}
inline void print(ll ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	rr ll tt=1;
	for (rr int i=1;i<=N;++i) (tt*=i)%=mod;
	inv[N]=ksm(tt,mod-2); inv[1]=1;
	for (rr int i=N;i>1;--i) inv[i-1]=inv[i]*i%mod; 
	for (rr int t=iut();t;--t){
		rr ll a=iut(),b=iut(),ans=inv[b];
		(a+=(1-iut())*(b-1))%=mod;
		for (rr ll i=a;i>a-b;--i) (ans*=i)%=mod;
		print(ans); putchar(10);
	}
	return 0;
}

洛谷 5136 sequence

分析

根據oeis,可以得到a(n)=3Fibonacci(n1)+Fibonacci(n2)+(nmod2),n>0a(n)=3∗Fibonacci(n−1)+Fibonacci(n−2)+(n\bmod2),n>0,所以矩陣乘法來一波


代碼

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int mod=998244353;
struct maix{int p[2][2];}A,ANS;
inline long long iut(){
    rr long long ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans;
}
inline maix mul(maix A,maix B,int k){
    rr maix C;
    for (rr int i=0;i<k;++i)
    for (rr int j=0;j<2;++j) C.p[i][j]=0;
    for (rr int i=0;i<k;++i)
    for (rr int j=0;j<2;++j)
    for (rr int k=0;k<2;++k)
    C.p[i][j]=(1ll*A.p[i][k]*B.p[k][j]+C.p[i][j])%mod;
    return C;
}
signed main(){
    for (rr int t=iut();t;--t){
        rr long long n=iut()-1; rr int k=(n&1)^1; n=n%1996488708;
        if (!n) {printf("1\n"); continue;}
        A.p[0][0]=1; A.p[0][1]=1; A.p[1][0]=1; A.p[1][1]=0;
        ANS.p[0][0]=1; ANS.p[0][1]=0; ANS.p[1][0]=0; ANS.p[1][1]=0;
        for (;n;n>>=1,A=mul(A,A,2))
            if (n&1) ANS=mul(ANS,A,1);
        printf("%d\n",(ANS.p[0][0]+(ANS.p[0][1]<<1)%998244353+k)%998244353);
    }
    return 0;
} 

洛谷 5137 polynomial

分析

萬惡的出題人卡掉了逆元,雖然我那時什麼都不會,可以像出題人那樣利用分治
在這裏插入圖片描述
注意乘法爆long long


代碼

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long ll;
ll a1,b1,n,a,b,mod;
inline ll iut(){
	rr ll ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline ll mo(ll a,ll b){return a+b>=mod?a+b-mod:a+b;}
inline ll mo2(ll a,ll b){return a<b?a-b+mod:a-b;}
inline ll mul(ll a,ll b){
	a%=mod,b%=mod;
	rr ll t=(long double)a*b/mod,ans=a*b-t*mod;
	if (ans<0) ans+=mod;
	    else if (ans>=mod) ans-=mod;
    return ans;
}
inline ll dfs(ll n){
	if (n<=1) return !n?1:mo(a,b);
	rr ll ans=dfs(n>>1);
	a1=mul(a1,a1),b1=mul(b1,b1);
	if ((n>>1)&1) a1=mul(a1,a),b1=mul(b1,b);
	return n&1?mul(mul(a1,a)+mul(b1,b),ans):mo2(mul(a1+b1,ans),mul(a1,b1));
}
signed main(){
	for (rr int t=iut();t;--t){
		n=iut(),a=iut(),b=iut(),mod=iut(),a1=b1=1;
		printf("%lld\n",dfs(n));
	}
	return 0;
}

洛谷 5138 fibonacci


後續

原諒我當時只會排列組合

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章