BestCoder Round #80 A B C hdu5667矩阵快速幂

来源:互联网 发布:乔杉咖啡厅网络剧 编辑:程序博客网 时间:2024/05/17 22:44



链接:戳这里


Lucky
 Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 65536/65536 K (Java/Others)
问题描述
    Vampire喜欢玄学,尤其喜欢研究幸运数字.

     对于一个数字集合S,定义关于S的幸运数字为无法用S中的数相加得到的最小的非负整数(每个数可以使用任意次).

     现在给定一个数集,如果能使用其中的数相加得到任意自然数,输出”YES”,否则输出”NO”.
输入描述
   第一行一个正整数T,为数据组数.

    每组数据第一行一个n,表示集合大小.

   接下来n个数,表示该数集里的数.

 1≤n≤10^​5,1≤T≤10,0≤a​i≤10^9
输出描述
  每组数据回答一个”YES”或”NO”.
输入样例
1
1
2
输出样例
NO


思路:

因为每个数可以用很多次,所以只要这个集合中有1,那么就可以加出所有的数来.注意最后要判定一下是否有0.


代码:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int n;int a[1000100];int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d",&n);        int flag1=0,flag2=0;        for(int i=1;i<=n;i++) {            scanf("%d",&a[i]);            if(a[i]==1){                flag1=1;            }            if(a[i]==0){                flag2=1;            }        }        if(flag1 && flag2) cout<<"YES"<<endl;        else cout<<"NO"<<endl;    }    return 0;}


Segment
 Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 65536/65536 K (Java/Others)
问题描述
  Rivendell非常神,喜欢研究奇怪的问题.

  今天他发现了一个有趣的问题.找到一条线段x+y=qx+y=q,令它和坐标轴在第一象限围成了一个三角形,然后画线连接了坐标原点和线段上坐标为整数的格点.

 请你找一找有多少点在三角形的内部且不是线段上的点,并将这个个数对PP取模后告诉他.
输入描述
  第一行一个数T,为测试数据组数.

  接下来每一行两个数qq,PP,意义如题目中所示.

q是质数且q≤10^18,1≤P≤10^18,1≤T≤10.
输出描述
   对每组数据,输出点的个数模PP后的值.
输入样例
1
2 107
输出样例
0


思路:

考虑一条以(0,0)为起点,(x,y)为终点的线段上格点的个数(不包含端点时),一定是gcd(x,y)-1,这个很显然吧.
然后整个网格图范围内的格点数目是q*(q-1)/2
所以答案就是q*(q-1)/2 − 所有线段上的格点的个数.
因为q是质数且a+b=q可以推出gcd(a,b)=1

 显然答案就是计算等腰直角三角形中的格点数 


代码:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;ll Q,P;ll kuai(ll q,ll num,ll mod){    ll ans=0;    ll base=q;    while(num){        if(num%2) ans=(ans+base)%mod;        num/=2;        base=(base+base)%mod;    }    return ans%mod;}int main(){    int T;    scanf("%d",&T);    while(T--){        cin>>Q>>P;        ll ans=(Q-1)/2;        ans=kuai(ans,Q-2,P);        cout<<(ans+P)%P<<endl;    }    return 0;}


Sequence 
 Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 65536/65536 K (Java/Others)
问题描述
 Lcomyn 是个很厉害的选手,除了喜欢写17kb+的代码题,偶尔还会写数学题.他找到了一个数列:



  他给了你几个数:nn,aa,bb,cc,你需要告诉他fn模p后的数值.
输入描述
第一行一个数T,为测试数据组数.

 每组数据一行,一行五个正整数,按顺序为nn,aa,bb,cc,pp.
1≤T≤10,1≤n≤10^18 ,1≤a,b,c≤10^9 ,p是质数且 p≤10​^9​​ +7.
输出描述
对每组数据输出一行一个数,输出fn对p取模后的数值.
输入样例
1
5 3 3 3 233
输出样例
190


思路:

观察递推式我们可以发现,所有的  f​i都是a的幂次,所以我们可以对f​i取一个以a为底的log

即g​i=log(a,fi)
那么递推式变成g​i =b+c∗g[​i−1]+g[​i−2]
​​ ,这个式子可以矩阵乘法
这题有一个小trick,注意a mod p=0的情况.


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<vector>#include <ctime>#include<queue>#include<set>#include<map>#include<stack>#include<iomanip>#include<cmath>#define mst(ss,b) memset((ss),(b),sizeof(ss))#define maxn 0x3f3f3f3f#define MAX 1000100///#pragma comment(linker, "/STACK:102400000,102400000")typedef long long ll;typedef unsigned long long ull;#define INF (1ll<<60)-1using namespace std;struct Matrix{    ll ma[3][3];    Matrix(){        for(int i=0;i<3;i++)            for(int j=0;j<3;j++)                ma[i][j]=0;    }};ll n,A,B,C,P;Matrix Mult(Matrix b,Matrix a,ll p){    Matrix ans;    for(int i=0;i<3;i++){        for(int j=0;j<3;j++){            for(int k=0;k<3;k++){                ans.ma[i][j]=(ans.ma[i][j]+a.ma[i][k]*b.ma[k][j]%p)%p;            }        }    }    return ans;}Matrix MPow(Matrix a,ll num,ll p){    Matrix tmp;    for(int i=0;i<3;i++) tmp.ma[i][i]=1;    while(num){        if(num%2) tmp=Mult(tmp,a,p);        a=Mult(a,a,p);        num/=2;    }    return tmp;}ll Pow(ll a,ll b,ll p){    ll ans=1;    while(b){        if(b%2) ans=ans*a%p;        a=a*a%p;        b/=2;    }    return ans;}int main(){    int T;    scanf("%d",&T);    while(T--){        cin>>n>>A>>B>>C>>P;        Matrix a,b;        a.ma[0][0]=1;a.ma[2][0]=B;        b.ma[0][0]=1;b.ma[1][2]=1;        b.ma[2][0]=B;b.ma[2][1]=1;b.ma[2][2]=C;        if(n==1) cout<<1<<endl;        else if(n==2) printf("%I64d\n",Pow(A,B,P));        else {            if(A%P==0) cout<<0<<endl;            else {                Matrix tmp=MPow(b,n-2,P-1);                Matrix ans=Mult(a,tmp,P-1);                ll anw=Pow(A,ans.ma[2][0],P);                printf("%I64d\n",anw);            }        }    }    return 0;}<strong></strong>


0 0
原创粉丝点击