10.24模拟

10.24结题报告

第一题:点亮灯笼

解题思路及代码:

/*模拟运算(n-m)!/(p1!*p2!*p3!...) * 2^L-1 两亮灯之间每个未亮的灯都是一种可能*/

#include<cstdio>

#include<cmath>

#include<algorithm>

using namespace std;

const int N=1e5+10;

const int mod=1e9+7;

long long n,m,sum,ha,cnt,w[N],t[N],prime[N];

bool check[N];

void first()

{

    for (int i=2;i<=n;i++)

       {

        if (!check[i])

                     prime[++sum]=i;

        for (int j=1;j<=sum&&prime[j]*i<=n;j++)

              {

            check[i*prime[j]]=1;

            if (i%prime[j]==0)

                            break;

        }

    }

}

pair<long long,long long>a[N];

long long Fpow(long long a,long long b)

{

    long long res=1;

    for (;b;b>>=1,a=a*a%mod)

              if (b&1)

                     res=res*a%mod;

    return res;

}

int main()

{

    //freopen("lantern.in","r",stdin);

    //freopen("lantern.out","w",stdout);

    scanf("%d%d",&n,&m);

    for (int i=1;i<=m;i++)

              scanf("%d",&w[i]);

    sort(w+1,w+m+1);

    first();

    if (w[1]>1)

              a[++cnt]=make_pair(w[1]-1,1);

    if (w[m]<n)

              a[++cnt]=make_pair(n-w[m],1);

    for(int i=2,l;i<=m;i++)

        if ((l=w[i]-w[i-1]-1)>0)

            a[++cnt]=make_pair(l,Fpow(2,l-1));

    for (int j=1;j<=sum;j++)

       {

        ha=n-m;

        if (ha<prime[j])

                     break;

        while (ha)

              {

            t[j]+=ha/prime[j];

            ha/=prime[j];

        }

    }

    for (int i=1;i<=cnt;i++)

       {

        for (int j=1;j<=sum;j++)

              {

            ha=a[i].first;

            if (ha<prime[j])

                            break;

            while (ha)

                     {

                t[j]-=ha/prime[j];

                ha/=prime[j];

            }

        }

    }

    long long ans=1;

    for (int i=1;i<=sum;i++)

        ans=(ans%mod*Fpow(prime[i],t[i])%mod)%mod;

    for (int i=1;i<=cnt;i++)

              ans=ans*a[i].second%mod;

    printf("%I64d",ans);

    return 0;

}

 

 

第二题:数据读取

解题思路及代码:

/*找出在不超时的情况下最远能到达的位置 找最大值最小 二分答案处理*/

#include<cstdio>

#include<cmath>

#include<algorithm>

using namespace std;

const int MAXN = 100005;

int n, m;

long long pos[MAXN],dest[MAXN],tot;

bool legal(long long l,long long r,long long cut)

{

       if (cut<=l)

              return (r-cut<=tot);

       if (cut>=r)

              return cut-l<=tot;

       return min(cut-l,r-cut)+r-l<=tot;

}

bool check()

{

       int i,j,st;

       for(i=1,j=0;i<=n;i++)

       {

              st=j+1;

              while (j<m && legal(dest[st],dest[j+1],pos[i]))

                     j++;

       }

       return j==m;

}

int main()

{

       //freopen("data.in", "r", stdin);

       //freopen("data.out", "w", stdout);

       int i;

       long long l, r;

       scanf("%d%d", &n, &m);

       for (i=1;i<=n;i++)

              scanf("%lld",&pos[i]);

       for (i=1;i<=m;i++)

              scanf("%lld", &dest[i]);

       l=0LL,r=20000000000LL;

       while (l<r)

       {

              tot=(l+r)>>1;

              if (check())

                     r=tot;

              else

                     l=tot+1;

       }

       printf("%lld\n", r);

       return 0;

}

 

 

第三题:道路重建

未解决

posted @ 2016-10-24 19:48  球痞丶小七  阅读(170)  评论(0编辑  收藏  举报