题目
3820,LOJ2026,3801
失分小结
估分
80+40+50=170
实际分数
0(70)+40+25=65(135)
第一题蜜汁运行错误…其实是有P70的
第三题…时间复杂度估算错误.
题解
T1
P70
cnt[i] 统计数字 i <script type="math/tex" id="MathJax-Element-8">i</script>的出现次数.
CODE
#include<cstdio>
#include<memory.h>
#include<cmath>
#define N 100000005
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
char cnt[N];
int main() {
int n,m,Q,k;
scanf("%d%d%d",&n,&m,&Q);
memset(cnt,0,sizeof cnt);
int nm=n>m?n:m;
FOR(i,1,m)FOR(j,1,n) {
if(1ll*i*j>nm)break;
cnt[i*j]++;
}
int CNT=0;
while(Q--) {
scanf("%d",&k);
CNT=0;
for(int i=1; i<=k; i++) {
CNT+=cnt[i];
if(CNT>=k) {
printf("%d\n",i);
break;
}
}
}
return 0;
}
P100
CODE
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,q,k;
bool check(int x) {
long long ans=0;
for(int i=1; i<=n; i++) {
if(i*i>x)break;
ans+=x/i-i+1;
if(i*i!=x)ans+=min(n,x/i)-i;
}
return ans>=k;
}
int main() {
scanf("%d%d%d",&n,&m,&q);
if(n>m)n=m;
while(q--) {
scanf("%d",&k);
int L=1,R=k,ans=k;
while(L<=R) {
int mid=(L+R)>>1;
if(check(mid)) {
ans=mid;
R=mid-1;
} else L=mid+1;
}
printf("%d\n",ans);
}
return 0;
}
T2
数学题,不多讲.
P40
CODE
#include<cstdio>
#include<memory.h>
#define N 105
#define P 1000000007
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
#define ROF(i,a,b) for(int i=(a),i##_END_=(b);i>=i##_END_;i--)
int u[N],r[N],f[N];
int C[N][N];
int Pow(int a,int n) {
int res=1;
while(n) {
if(n&1)res=(1ll*res*a)%P;
n>>=1;
a=(1ll*a*a)%P;
}
return res;
}
int main() {
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
FOR(i,1,m)scanf("%d",u+i);
FOR(i,1,m)scanf("%d",r+i);
C[0][0]=C[1][0]=C[1][1]=1;
FOR(i,2,101) {
C[i][0]=C[i][i]=1;
FOR(j,1,i-1)C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
}
ROF(i,n-1,k) {
f[i]=C[n-1][i];
FOR(j,1,m)f[i]=1ll*f[i]*C[n-1-i][r[j]-1]%P;
FOR(j,i+1,n-1)f[i]=(f[i]-1ll*f[j]*C[j][i]%P+P)%P;
}
int ans=f[k];
FOR(i,1,m) {
int res=0;
FOR(j,0,u[i])res=(res+1ll*Pow(u[i]-j,r[i]-1)*Pow(j,n-r[i]))%P;
ans=1ll*ans*res%P;
}
printf("%d\n",ans);
return 0;
}
P100
CODE
#include<cstdio>
#include<cstdlib>
#define N 105
#define P 1000000007
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
#define ROF(i,a,b) for(int i=(a),i##_END_=(b);i>=i##_END_;i--)
int u[N],r[N],f[N],g[N];
int inv[N],C[N][N];
inline int Pow(int a,int n) {
int res=1;
while(n) {
if(n&1)res=1ll*res*a%P;
n>>=1;
a=1ll*a*a%P;
}
return res;
}
//#define DEBUG
int main() {
int n,m,k,ans=0;
scanf("%d%d%d",&n,&m,&k);
FOR(i,1,m)scanf("%d",u+i);
FOR(i,1,m)scanf("%d",r+i);
inv[1]=C[0][0]=C[1][0]=C[1][1]=1;
FOR(i,2,101) {
inv[i]=1ll*inv[P%i]*(P-P/i)%P;
C[i][0]=C[i][i]=1;
FOR(j,1,i-1)C[i][j]=(C[i-1][j]+C[i-1][j-1])%P;
#ifdef DEBUG
printf("%d\t",inv[i]);
#endif
}
#ifdef DEBUG
puts("");
FOR(i,0,10) {
FOR(j,0,i)printf("%d ",C[i][j]);
puts("");
}
FOR(j,0,100)printf("%d ",C[100][j]);
puts("");
#endif
ROF(i,n-1,k) {
f[i]=C[n-1][i];
FOR(j,1,m)f[i]=1ll*f[i]*C[n-1-i][r[j]-1]%P;
FOR(j,i+1,n-1)f[i]=(f[i]-1ll*f[j]*C[j][i]%P+P)%P;
#ifdef DEBUG
printf("%d ",f[i]);
#endif
}
#ifdef DEBUG
puts("");
#endif
ans=f[k];
FOR(i,1,m) {
FOR(j,1,n) {
g[j]=(Pow(u[i]+1,j+1)-1-u[i])%P;
FOR(ii,1,j-1)g[j]=(g[j]-1ll*g[ii]*C[j+1][ii]%P)%P;
g[j]=1ll*g[j]*inv[j+1]%P;
#ifdef DEBUG
printf("%d ",g[i]);
#endif
}
#ifdef DEBUG
puts("");
#endif
int res=0,flag=1;
FOR(j,0,r[i]-1) {
res=(1ll*res+1ll*C[r[i]-1][j]*Pow(u[i],r[i]-1-j)%P*g[n-r[i]+j]%P*flag)%P;
flag=-flag;
}
ans=1ll*ans*res%P;
}
printf("%d\n",(ans+P)%P);
return 0;
}//shabi的调试语句请忽略.
T3
P40
CODE
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ll long long
using namespace std;
int n,m,A[1005][1005];
int dp[55][55];
void chk_mx(int &x,int y){if(x<y)x=y;}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)scanf("%d",&A[i][j]);
while(m--){
memset(dp,-1,sizeof(dp));
dp[0][0]=0;
int x,y;
scanf("%d%d",&x,&y);
FOR(i,1,n){
FOR(j,1,i){
if(i==x&&j==y)continue;
if(dp[i-1][j]!=-1)chk_mx(dp[i][j],dp[i-1][j]+A[i][j]);
if(dp[i-1][j-1]!=-1)chk_mx(dp[i][j],dp[i-1][j-1]+A[i][j]);
}
}
int ans=-1;
FOR(i,1,n)chk_mx(ans,dp[n][i]);
printf("%d\n",ans);
}
return 0;
}
P100
CODE
#include<cstdio>
#include<memory.h>
#define N 1005
#define max(x,y) ((x)>(y)?(x):(y))
inline void Max(int &x,int y){if(x<y)x=y;}
inline void rd(int &x) {
x=0;static char c;
while(c=getchar(),c<48);
do x=(x<<3)+(x<<1)+(c&15);
while(c=getchar(),c>47);
}
int A[N][N],dis[N],dp[2][N][N];
bool Q[N][N];
int main() {
int n,m;
rd(n),rd(m);
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
rd(A[i][j]);
memset(dis,-1,sizeof dis);
for(int i=n; i>=1; i--)
for(int j=1; j<=i; j++)
dp[0][i][j]=A[i][j]+max(dp[0][i+1][j],dp[0][i+1][j+1]);
for(int i=1; i<=n; i++) {
int cnt=0;
for(int j=1; j<=i; j++){
dp[1][i][j]=A[i][j]+max(dp[1][i-1][j],dp[1][i-1][j-1]);
if(dp[0][i][j]+dp[1][i][j]-A[i][j]==dp[0][1][1])Q[i][j]=1,cnt++;
else Max(dis[i],dp[0][i][j]+dp[1][i][j]-A[i][j]);
}
if(cnt>1)for(int j=1; j<=i; j++)Q[i][j]=0;
}
int x,y;
while(m--) {
rd(x),rd(y);
if(!Q[x][y])printf("%d\n",dp[0][1][1]);
else printf("%d\n",dis[x]);
}
return 0;
}