bc 80

难得打一场bc,FST了两道,显然我还不在最佳状态,但是我已经感觉到提高了。

这一场比赛开始一个小时后才看的题,当时只剩40分钟,不过由于我急于涨分,所以决定看题,先看C题,很简单的矩阵快速幂+费马小定理降幂,但是调了好久。。。确实不在状态。。。不过还是写完了,,,然后剩下十分钟顺手过了B和A题。最后挂了两道,A题是自己没考虑周到,C题是之前用费马小定理的时候一直没注意不互质的时候,也就是a%p==0的时候。然后自己确实也没认真去对待比赛,最后的hack没提前造数据,随手hack,当然hack失败,提交代码之前也没考虑极端情况,顺手一交,也难怪FST。

D题也是可以做的,就是个拓展中国剩余定理。

C题:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

ll n,a,b,c,p;
ll p1;

struct Matrix
{
    ll a[3][3];
    friend Matrix operator*(Matrix A,Matrix B)
    {
        Matrix C;MS0(C.a);
        REP(i,0,2) REP(j,0,2) REP(k,0,2) C.a[i][j]=(C.a[i][j]+p1*3+A.a[i][k]*B.a[k][j])%p1;
        return C;
    }
};

Matrix qpow(Matrix n,ll k)
{
    Matrix res;MS0(res.a);
    REP(i,0,2) res.a[i][i]=1;
    while(k){
        if(k&1) res=res*n;
        n=n*n;
        k>>=1;
    }
    return res;
}

ll g(ll n)
{
    if(n==1) return 0;
    if(n==2) return b;
    Matrix tmp;MS0(tmp.a);
    tmp.a[0][0]=(c+1)%p1;
    tmp.a[0][1]=(p1*3+1-c)%p1;
    tmp.a[0][2]=(p1*3-1)%p1;
    tmp.a[1][0]=1;
    tmp.a[2][1]=1;
    tmp=qpow(tmp,n-3);
    ll a[3]={(b*c+b)%p1,b,0};
    ll res=0;
    REP(i,0,2) res=(res+3*p1+tmp.a[0][i]*a[i])%p1;
    return res;
}

ll qpow2(ll n,ll k,ll p)
{
    ll res=1;
    while(k){
        if(k&1) res=(res*n)%p;
        n=(n*n)%p;
        k>>=1;
    }
    return res;
}

ll solve()
{
    if(a%p==0) return 0;
    ll x=g(n);
    ll res=qpow2(a,x,p);
    return res;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%I64d%I64d%I64d%I64d%I64d",&n,&a,&b,&c,&p);
        p1=p-1;
        printf("%I64d\n",solve());
    }
    return 0;
}
View Code

D题:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef  long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n;
int a[maxn],b[maxn];
int pos[maxn];
ll Y[maxn],Z[maxn];

void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if(b==0){
        x=1;y=0;d=a;
        return;
    }
    exgcd(b,a%b,d,y,x);
    y-=a/b*x;
}

ll MLE(ll a,ll b,ll n)
{
    ll x,y,d;
    exgcd(a,n,d,x,y);
    if(b%d) return -1;
    x*=b/d;
    return (x%n+n)%n;
}

ll LCM(ll a,ll b)
{
    return a/__gcd(a,b)*b;
}

ll ex_china(ll *a,ll *m,int n)
{
    ll A=0,M=1;
    REP(i,1,n){
        ll k=MLE(m[i],A-a[i],M);
        if(k==-1) return -1;
        A=k*m[i]+a[i];
        M=LCM(M,m[i]);
    }
    if(A%M==0) return M;
    return (A+M)%M;
}

int main()
{
    freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%d",&n);
        REP(i,1,n) scanf("%d",&a[i]),b[a[i]]=i;
        int s=0;
        int cnt=n;
        vector<int> v;
        REP(i,1,n) v.push_back(i);
        REP(i,1,n){
            for(int j=0;j<v.size();j++){
                if(v[j]==b[i]){
                    Y[i]=j+1-s;
                    Z[i]=(int)v.size();
                    vector<int>::iterator it=(v.begin()+j);
                    v.erase(it);
                    s=j;
                    break;
                }
            }
        }
        ll ans=ex_china(Y,Z,n);
        if(ans==-1) puts("Creation August is a SB!");
        else printf("%I64d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2016-04-18 15:48  __560  阅读(348)  评论(0编辑  收藏  举报