20150809解題報告

【T1】congruence

數學題
在只有一塊的情況下,答案爲pk(p1)k1
其中k爲單一塊的大小
對於幾個塊的情況考慮dp
dp[i][j]表示做第 i 塊 j 的方案總數
可以想到線性的遞推代替之
代碼如下:

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

typedef long long LL;

int mod;

inline void rd(int& x)
{
    static char ch;
    for (;!isdigit(ch=getchar()););
    for (x=ch-48;isdigit(ch=getchar());x=x*10+ch-48);
}

inline int pw(int x,int y)
{
    int rt=1;
    for (;y;y>>=1,x=x*(LL)x%mod)
        if (y&1) rt=rt*(LL)x%mod;
    return rt;
}

inline void solve(void)
{
    int n,p,x,ans,tot,t;
    rd(n);rd(x);rd(p);rd(mod);
    ans=!x;tot=1;
    for (int i=1;i<=n;++i)
    {
        rd(x);t=pw(p,x);
        ans=(ans*(LL)t+pw(p-1,x-1)*(LL)(tot-p*(LL)ans%mod))%mod;
        tot=tot*(LL)t%mod;
    }
    printf("%d\n",(ans+mod)%mod);
}

int main()
{
    freopen("congruence.in","r",stdin);
    freopen("congruence.out","w",stdout);
    int t;
    for (rd(t);t--;) solve();
    return 0;
}

【T2】 permutation

首先是一個合唱隊形的問題,蛇形排列棒的要死
然後排個序離散化,各種分類討論
排列時左端點爲X1,右端點爲X2
X1 != X2 只有一種放法
X1 = X2 根據字典序再討論一下
大概就是這樣
簡直被噁心死,看代碼吧

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

const int N=100000+5;

int n,m,l,r,v[N],q[N],num[N],L[N],R[N],ans[N];

inline void rd(int& x)
{
    static char ch;
    for (;!isdigit(ch=getchar()););
    for (x=ch-48;isdigit(ch=getchar());x=x*10+ch-48);
}

inline bool cmp(const int& x,const int& y){return v[x]<v[y] ||(v[x]==v[y] && x<y);}

inline void solve(void)
{
    rd(n);m=0;l=0;r=n+1;
    for (int i=1;i<=n;++i) rd(v[i]),q[i]=i;
    sort(q+1,q+n+1,cmp);
    for (int i=1,j;i<=n;i=j)
    {
        L[++m]=i;num[m]=v[q[i]];
        for (j=i;j<=n && v[q[j]]==v[q[i]];++j);
        R[m]=j-1;
    }
    ans[r]=0;
    for (int i=1;i<=m;)
    {
        if (L[i]>R[i] && ++i>m) break;
        if (v[ans[l]]<v[ans[r]]) ans[++l]=q[L[i]++];else
        if (v[ans[l]]>v[ans[r]]) ans[--r]=q[R[i]--];else
        if (num[i]==v[ans[l]])
        {
            if ((i+1<=m && q[L[i+1]]<q[L[i]])||(i+2<=m && L[i+1]==R[i+1] && q[L[i+2]]<q[L[i]]))
                while (R[i]>=L[i])  ans[--r]=q[R[i]--];
            else ans[++l]=q[L[i]++];
        }else{
            if (i+1<=m && L[i]==R[i] && q[L[i+1]]<q[L[i]])
                ans[--r]=q[R[i]--];
            else ans[++l]=q[L[i]++];
        }
    }
    for (int i=1;i<=n;++i) printf("%d%c",ans[i]," \n"[i==n]);
}

int main()
{
    freopen("permutation.in","r",stdin);
    freopen("permutation.out","w",stdout);
    int t;
    for (rd(t);t--;) solve();
    return 0;
}

【T3】recursion

Fibonacci數列前n項和:Sn=Fn+2
知道這個大概會容易一點
部分分還是很好拿的
100%套一個矩陣乘法

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

typedef long long LL;

const int N=40+3;
const int L=N*2;
const int mod=1000000009;

int n,m,l,f[L][L],g[L][L],rt[L][L],t[L][L],v[L],w[L];

inline void rd(int& x)
{
    static char ch;
    static bool flag;
    for (flag=0;!isdigit(ch=getchar());flag=(ch=='-'));
    for (x=ch-48;isdigit(ch=getchar());x=x*10+ch-48);
    if (flag) x=-x;
}

inline void mul(int x)
{
    for (int i=0;i<l;++i)
        for (int j=0;j<l;++j)
            rt[i][j]=(i==j),g[i][j]=f[i][j];
    while (x)
    {
        if (x&1)
        {
            for (int i=0;i<l;++i)
                for (int j=0;j<l;++j)
                    t[i][j]=rt[i][j],rt[i][j]=0;
            for (int i=0;i<l;++i)
                for (int k=0;k<l;++k)
                    if (t[i][k])
                        for (int j=(k<m)?0:m;j<l;++j)
                            if (g[k][j])
                                rt[i][j]=(rt[i][j]+t[i][k]*(LL)g[k][j])%mod;
        }
        if ((x>>=1))
        {
            for (int i=0;i<l;++i)
                for (int j=0;j<l;++j)
                    t[i][j]=g[i][j],g[i][j]=0;
            for (int i=0;i<l;++i)
                for (int k=0;k<l;++k)
                    if (t[i][k])
                        for (int j=(k<m)?0:m;j<l;++j)
                            if (t[k][j])
                                g[i][j]=(g[i][j]+t[i][k]*(LL)t[k][j])%mod;
        }
    }
}

int main()
{
    freopen("recursion.in","r",stdin);
    freopen("recursion.out","w",stdout);
    rd(n);rd(m);l=m*2;
    for (int i=1;i<=m;++i) rd(f[m-i][m-1]);
    for (int i=0;i<m;++i) rd(v[i]);
    for (int i=1;i<m;++i) f[i][i-1]=1;
    for (int i=0;i<m;++i) f[i][m+i]=f[m+i][m+i]=1;
    for (int i=1,x;i<=n;++i)
    {
        rd(x);mul(x);
        for (int j=0;j<l;++j)
        {
            w[j]=0;
            for (int k=0;k<l;++k)
                w[j]=(w[j]+v[k]*(LL)rt[k][j])%mod;
        }
        for (int j=0;j<m;++j) v[j]=w[m+j];
    }
    printf("%d\n",(v[0]+mod)%mod);
    return 0;
}

尾聲

【你說的是人話嗎?】
–【某智障不寫題解我有什麼辦法?】
–【那你怎麼還寫了東西】
–【這些**他口述了半個小時!!!!!】

End.

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