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;
}
第三题:道路重建
未解决