Bestcoder #80 题解 (待补)

来源:互联网 发布:avast淘宝激活 编辑:程序博客网 时间:2024/05/16 14:48

Lucky

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

    int T=read();    while (T--) {        int n=read();        bool b=0,b2=0;        For(i,n) {            int p=read();            b|=(p==1);            b2|=(p==0);        }        if (b&&b2) puts("YES");        else puts("NO");    }

Segment

x+y=q和坐标轴在第一象限围成了一个三角形,然后画线连接了坐标原点和线段上坐标为整数的格点.
求有多少点在三角形的内部且不是线段或连线上的点,对P取模
q是质数,q,P<=10^18

q是质数,那些后面的连线不会和三角形内部格点相交
pick公式

import java.io.*;import java.util.*;import java.math.*;public class Main{    public static void main(String args[])    {        Scanner cin = new Scanner(System.in);        int T=cin.nextInt();          while ((T--)>0) {              BigInteger q = cin.nextBigInteger();              BigInteger P = cin.nextBigInteger(),ans = new BigInteger("1");              BigInteger a = q.multiply(q).divide(BigInteger.valueOf(2));            a = a.add(BigInteger.ONE);            a = a.subtract(q.multiply(BigInteger.valueOf(3)).divide(BigInteger.valueOf(2)));            System.out.println(a.mod(P));        }      }}

Sequence

已知n,a,b,c,p

fn=1,ab,abfcn1fn2,n=1n=2otherwise

1T10,1n1018,1a,b,c109,p是质数且p109+7
fnp

两边对a取对数,矩乘快速幂,记得取对数后mod p 变成 mod ϕ(p)
还有a mod p=0时n>=2答案是0,
这时不能用费小,因为gcd(a,p)=p

aφ(n)1(modn)(gcd(a,n)=1)

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<functional>#include<iostream>#include<cmath>#include<cctype>#include<ctime>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  #define Lson (x<<1)#define Rson ((x<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)typedef long long ll;ll F;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} #define eps  #define MAXN (10)struct M  {      int n,m;      ll a[MAXN][MAXN];      M(int _n=0){n=m=_n;MEM(a);}     M(int _n,int _m){n=_n,m=_m;MEM(a);}    void mem (int _n=0){n=m=_n;MEM(a);}    void mem (int _n,int _m){n=_n,m=_m;MEM(a);}    friend M operator*(M a,M b)      {          M c(a.n,b.m);          For(k,a.m)            For(i,a.n)                  For(j,b.m)                      c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%F;          return c;         }      friend M operator+(M a,M b)      {          For(i,a.n)              For(j,a.m)                  a.a[i][j]=(a.a[i][j]+b.a[i][j])%F;          return a;    }      void make_I(int _n)      {          n=m=_n; MEM(a)        For(i,n) a[i][i]=1;      }  }A,B;M pow2(M a,ll b)  {      M c;c.make_I(a.n);        static bool a2[1000000];        int n=0;while (b) a2[++n]=b&1,b>>=1;        For(i,n)        {            if (a2[i]) c=c*a;            a=a*a;        }        return c;    }ll pow2(ll a,int b,ll p)  //a^b mod p {      if (b==0) return 1%p;      if (b==1) return a%p;      ll c=pow2(a,b/2,p);      c=c*c%p;      if (b&1) c=c*a%p;      return c;  }  int main(){//  freopen("C.in","r",stdin);//  freopen(".out","w",stdout);    int T=read();    while (T--) {        ll n,a,b,c;        cin>>n>>a>>b>>c>>F;        if (n==1) {            cout<<1%F<<endl;        } else if (n==2) {            cout<<pow2(a,b,F)<<endl;        } else if (a%F==0) {            puts("0");        }else {            A.mem(3);            A.a[1][1]=c;            A.a[1][2]=A.a[2][1]=A.a[3][3]=1;            A.a[1][3]=b;            F--;             A=pow2(A,n-2);            ll ans=add(mul(A.a[1][1] , b), A.a[1][3]);            F++;            cout<<pow2(a,ans,F)<<endl;        }    }    return 0;}

Circle

n个同学围成一个圈做约瑟夫游戏,以同学1为起点,开始计数,计数到第k个同学,该同学出圈.出圈的同学将不参与之后的计数.
求已知出圈序列的最小的k

模线性方程,待填坑
考虑2个模线性方程
{X=a0(modm0)X=a1(modm1)
xm0+a0xm0ym1xm0x(m0/g)=ym1+a1=a1a0=a1a0(modm1)=(a1a0)/g(modm1/g)(1)

g=gcd(m0,m1).
则有解条件为g|abs(a1a0)
xm0+ym1=gcd(m0,m1)
xm0x(m0/g)xa1a0g(m0/g)=g(modm1)=1(modm1/g)=(a1a0)/g(modm1/g)(2)
对比(1),(2),
x=xa1a0g+k(m1/g),k
X=[xa1a0g+k(m1/g)]m0+a0
X=xa1a0g+a0(mod(m0m1)/g)

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<functional>#include<iostream>#include<cmath>#include<cctype>#include<ctime>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  #define Lson (x<<1)#define Rson ((x<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define PRi(a,n) Rep(i,n-1) cout<<a[i]<<' '; cout<<a[n-1]<<endl;#define PRi2D(a,n,m) For(i,n) { \                        For(j,m-1) cout<<a[i][j]<<' ';\                        cout<<a[i][m]<<endl; \                        } typedef long long ll;ll F;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} void gcd(ll a,ll b,ll &d,ll &x,ll &y) {    if (!b) {d=a,x=1,y=0;   }    else {gcd(b,a%b,d,y,x); y-=x*(a/b); }}// x mod m0=a0,x mod m =a,noSolution return 0 //初始可令 m0 = 1 ,a0 = 0 bool china(ll &m0,ll &a0,ll m,ll a)  {    ll g,x,y;    ll c=abs(a-a0);    gcd(m0,m,g,x,y);    if ( c % g ) return 0;    x*=(a-a0)/g;     x%=m/g;    a0=x*m0+a0;    m0*=m/g;    a0%=m0;    if(a0<0) a0+=m0;    return 1;}#define MAXN (1000)int a[MAXN],h[MAXN];bool b[MAXN];int q1[MAXN],m1[MAXN];int main(){//  freopen("D.in","r",stdin);    int T=read();    while (T--) {        int n = read();        For(i,n) a[i]=read();        For(i,n) h[a[i]-1]=i-1;        MEM(b)        int p=0;        Rep(i,n)        {            m1[i]=n-i;              int q=0;            while(p!=h[i]) {                q+=(!b[p]);                p=(p+1)%n;             }            q=(q+1)%m1[i];            q1[i]=q;                b[p]=1;        }        ll m0=1,a0=0;        bool flag=1;        Rep(i,n) {            flag=china(m0,a0,m1[i],q1[i]);            if (!flag) break;        }        if (flag) printf("%I64d\n",(!a0)?m0:a0);        else puts("Creation August is a SB!");    }    return 0;}

Road

n个地点,m个道路信息,每个道路信息用(a,b,c,d,w)表示,意为对任意两个地点x,y,满足axb,cyd,则在x,y两地之间修一条道路,走过这条道路消耗的时间为w.你可以做k次飞行,每次飞行可以瞬间通过某条已有的路径,从某个点抵达另一个点.
求从1号点到n号点消耗的最少时间.
1n5104,1m104,0k10,1w103

待填坑

0 0
原创粉丝点击