7.15 集训总结

7.15 集训总结

A、数列

题目描述

7.15 集训总结
7.15 集训总结

分析

非常显然的矩阵快速幂
首先我们要构造如下的两个矩阵
(left[ begin{matrix} b &c &d &1\1 &0 &0 &0\ 0 &1 &0 &0\0 &0 &0 &1end{matrix} right])

(left[ begin{matrix} a_2 &0 &0 &0\a_1 &0 &0 &0\ a_0 &0 &0 &0\e &0 &0 &0end{matrix} right])

然后做矩阵乘法就可以了

要注意的是,矩阵乘法不满足交换律,所以哪一行哪一列相乘一定要搞清

而且比较恶心的是,由于模数为(10^{18}),所以两个数相乘会爆(long long),因此在做乘法的时候还要用到高精度

考试的时候写完矩阵快速幂又写了一个暴力的对拍,却一直出错

后来输出中间变量才发现是暴力溢出了,最后5分钟才交上

代码

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const ll mod=1000000000000000000;
struct jz{
    ll sz[10][10];
    jz(){
        memset(sz,0,sizeof(sz));
    }
}now,ans;
ll jla[100],jlb[100],jg[100];
ll wdcf(ll aa,ll bb){
    memset(jla,0,sizeof(jla));
    memset(jlb,0,sizeof(jlb));
    ll cnta=0,cntb=0;
    while(aa){
        jla[++cnta]=aa%10;
        aa/=10;
    }
    while(bb){
        jlb[++cntb]=bb%10;
        bb/=10;
    }
    memset(jg,0,sizeof(jg));
    for(ll i=1;i<=cnta;i++){
        for(ll j=1;j<=cntb;j++){
            jg[i+j-1]+=jla[i]*jlb[j];
        }
    }
    ll mans=0,jl=1;
    for(ll i=1;i<=19;i++){
        if(jg[i]>=10){
            ll zj=jg[i]/10;
            jg[i+1]+=zj;
            jg[i]%=10;
        }
        mans+=jg[i]*jl;
        jl*=10;
    }
    return mans;
}
jz cf(jz aa,jz bb){
    jz cc;
    memset(cc.sz,0,sizeof(cc.sz));
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            for(int k=1;k<=4;k++){
                cc.sz[i][j]=(cc.sz[i][j]%mod+wdcf(aa.sz[i][k],bb.sz[k][j])%mod)%mod;
            }
        }
    }
    return cc;
}
int num[50],cnt=0;
int main(){
    ll a0,a1,a2,b,c,d,e,n;
    scanf("%llu%llu%llu%llu%llu%llu%llu%llu",&a0,&a1,&a2,&b,&c,&d,&e,&n);
    ans.sz[1][1]=a2%mod;
    ans.sz[2][1]=a1%mod;
    ans.sz[3][1]=a0%mod;
    ans.sz[4][1]=e%mod;
    now.sz[1][1]=b%mod;
    now.sz[1][2]=c%mod;
    now.sz[1][3]=d%mod;
    now.sz[1][4]=1;
    now.sz[2][1]=1;
    now.sz[3][2]=1;
    now.sz[4][4]=1;
    ll jg;
    if(n==0) jg=a0;
    else if(n==1) jg=a1;
    else if(n==2) jg=a2;
    else {
        ll zs=n-2;
        while(zs){
            if(zs&1) ans=cf(now,ans);
            now=cf(now,now);
            zs>>=1;
        }
        jg=ans.sz[1][1]%mod;
    }
    while(jg){
        num[++cnt]=jg%10;
        jg/=10;
    }
    int dy=18-cnt;
    for(int i=1;i<=dy;i++){
        printf("0");
    }
    printf("%llun",ans.sz[1][1]%mod);
    return 0;
}

B、旗木双翼

题目描述

7.15 集训总结
7.15 集训总结
7.15 集训总结
7.15 集训总结

分析

很有思维含量的一道题
我们可以把题意转换成一个人从坐标为((n,m))的开始走,走到坐标为((0,0))的点
而且只能向上向右走的方案数
看下面的图可能会更好理解一些
7.15 集训总结
因此最终的结果就是(C_{n+m}^{n})
因为结果要取模,而且涉及到除法运算,因此要求逆元

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=200005;
ll ny[maxn];
int main(){
    ll n,m;
    scanf("%lld%lld",&n,&m);
    ny[1]=1;
    for(ll i=2;i<=n+m;i++){
        ny[i]=(mod-mod/i)*ny[mod%i]%mod;
    }
    ll ans=1;
    for(ll i=1;i<=n+m;i++){
        ans=ans*i%mod;
    }
    for(ll i=1;i<=n;i++){
        ans=ans*ny[i]%mod;
    }
    for(ll i=1;i<=m;i++){
        ans=ans*ny[i]%mod;
    }
    printf("%lldn",ans%mod);
    return 0;
}

C、乌龟棋

题目描述

7.15 集训总结
7.15 集训总结
7.15 集训总结
7.15 集训总结

分析

我们设(f[a][b][c][d])为使用了(a)张标有数字(1)的卡片,(b)张标有数字(2)的卡片,(c)张标有数字(3)的卡片,(d)张标有数字(4)的卡片所能得到的最大得分
状态转移方程就很显然了

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 45;
int f[maxn][maxn][maxn][maxn];
const int N = 400;
int nn[N],mm[N];
int n,m;
int sum[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        scanf("%d",&nn[i]);
    }
    for(int i=1;i<=m;++i){
        scanf("%d",&mm[i]);
        sum[mm[i]]++;
    }
    for(int a=0;a<=sum[1];++a){
        for(int b=0;b<=sum[2];++b){
            for(int c=0;c<=sum[3];++c){
                for(int d=0;d<=sum[4];++d){
                    int jl1=0,jl2=0,jl3=0,jl4=0;
                    if(a)jl1=f[a-1][b][c][d];
                    if(b)jl2=f[a][b-1][c][d];
                    if(c)jl3=f[a][b][c-1][d];
                    if(d)jl4=f[a][b][c][d-1];
                    f[a][b][c][d]=max(max(jl1,jl2),max(jl3,jl4))+nn[a+2*b+3*c+4*d+1];
                }
            }
        }
    }
    printf("%dn",f[sum[1]][sum[2]][sum[3]][sum[4]]);
    return 0;   
}

D、假面舞会

题目描述

7.15 集训总结
7.15 集训总结
7.15 集训总结

分析

传送门

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int head[maxn],tot=2;
struct asd{
    int from,to,next,val;
}b[maxn];
void ad(int aa,int bb,int cc){
    b[tot].from=aa;
    b[tot].to=bb;
    b[tot].next=head[aa];
    b[tot].val=cc;
    head[aa]=tot++;
}
bool vis[maxn];
int dis[maxn],ans;
void DFS(int now){
    vis[now]=1;
    for (int i=head[now];i!=-1;i=b[i].next){
        int u=b[i].to;
        if(!vis[u]){
            dis[u]=dis[now]+b[i].val;
            DFS(u);
        } else {
            if(ans==0) ans=abs(dis[now]+b[i].val-dis[u]);
            else ans=__gcd(ans,abs(dis[now]+b[i].val-dis[u]));
        }
    }
}
int mmin,mmax;
int jud[maxn];
void dfs(int now){
    mmax=max(mmax,dis[now]);
    mmin=min(mmin,dis[now]);
    vis[now]=1;
    for(int i=head[now];i!=-1;i=b[i].next){
        if(!jud[i]){
            jud[i]=jud[i^1]=1;
            int u=b[i].to;
            dis[u]=dis[now]+b[i].val;
            dfs(u);
        }
    }
}
int main(){
    memset(head,-1,sizeof(head));
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int aa,bb;
        scanf("%d%d",&aa,&bb);
        ad(aa,bb,1);
        ad(bb,aa,-1);
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]) DFS(i);
    }
    if(ans){
        if(ans<3) printf("-1 -1n");
        else {
            int now;
            for(int i=3;i<=ans;i++){
                if(ans%i==0) {
                    now=i;
                    break;
                }
            }
            printf("%d %dn",ans,now);
        }
        return 0;
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            mmin=mmax=dis[i]=0;
            dfs(i);
            ans+=mmax-mmin+1;
        }
    }
    if(ans>=3) printf("%d 3n",ans);
    else printf("-1 -1n");
    return 0;
}

原文链接: https://www.cnblogs.com/liuchanglc/p/13307833.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    7.15 集训总结

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/366564

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午4:50
下一篇 2023年3月2日 下午4:51

相关推荐