8.28题解
博客咕的稍多,题稍改不完,坑只能尽量填了
T1
这道题其实考的是对题意的转化,当然他考场上给的错误样例解释让我懵了好久
我们先来思考一下,对于这道题来说$\sum\limits_{i=0}^{n{\times}m}i{\times}{\int_i}{\%}(10^9+7)$有没有什么实际的涵义?炼字个数为$i$的总方案数乘上$i$,那显然就是所有方案数中的所有炼字数的总和,那么我们就可以按位考虑贡献了,对于整个矩阵中的某一位,如果在这一位上填的数为$x$,那么和他在同一行或同一列上的位置能填的数的方案数就是$x-1$,一共有$(n+m-2)$的位置,所以方案数就是$x-1^{n+m-2}$,剩余的位置随便填就可以保证这个选定的位置是炼字,所以总方案数就是$x-1^{n+m-2}{\times}k^{n*m-n-m-1}$,把$x$枚举一遍,最后再乘以$n*m$就可以了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define ll long long 5 #define int long long 6 #define mod 1000000007 7 using namespace std; 8 int n,m,k; 9 ll ans; 10 ll ksm(ll a,int b) 11 { 12 ll ans=1; 13 while(b) 14 { 15 if(b&1) ans=(ans*a)%mod; 16 b=b>>1; a=(a*a)%mod; 17 } 18 return ans%mod; 19 } 20 main() 21 { 22 scanf("%lld%lld%lld",&n,&m,&k); 23 for(int i=1;i<=k;++i) 24 ans=(ans+(ksm((i-1),n+m-2)*ksm(k,n*m-n-m+1))%mod)%mod; 25 ans=((ans*n)%mod*m)%mod; 26 printf("%lld\n",ans); 27 return 0; 28 }
T2
考场上打了个二分复杂度是$O(n^3logn)$,跑大样例的时候发现慢的不像话,后来看样例,发现有连续很多个询问的答案是一样的,于是可以直接先$check$上一个答案,如果成立就直接输出答案,没必要二分了,这个优化直接就水到了95分,然后本来以为这算法过不去了,结果数据稍水,我们可以记下来上一个答案是哪个区间,如果这次的修改没有影响这个区间,那么就可以直接输出答案了,然后就过了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #define maxn 1010 6 using namespace std; 7 const int L=1<<20|1; 8 char buffer[L],*S,*T; 9 #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++) 10 inline int read() 11 { 12 register int ret; register char r; 13 while(r=getchar(),r<'0'||r>'9');ret=r-48; 14 while(r=getchar(),r>='0'&&r<='9')ret=ret*10+r-48; 15 return ret; 16 } 17 int n,m,q,x,y,l,r,ans,prex,prey; 18 int a[maxn][maxn],qz[maxn][maxn]; 19 inline bool check(int x) 20 { 21 for(int i=x;i<=n;++i) 22 for(int j=x;j<=m;++j) 23 { 24 if(!a[i][j]) continue; 25 int tot=qz[i][j]-qz[i-x][j]-qz[i][j-x]+qz[i-x][j-x]; 26 if(tot==x*x) { 27 prex=i,prey=j; 28 return 1; 29 } 30 } 31 return 0; 32 } 33 int main() 34 { 35 n=read(); m=read(); q=read(); 36 for(int i=1;i<=n;++i) 37 { 38 for(int j=1;j<=m;++j) 39 { 40 char c=getchar(); 41 while(c!='-'&&c!='+') c=getchar(); 42 if(c=='+') a[i][j]=1; 43 qz[i][j]=qz[i-1][j]+qz[i][j-1]-qz[i-1][j-1]+a[i][j]; 44 } 45 } 46 l=1; r=min(n,m); 47 while(l<=r) 48 { 49 int mid=(l+r)>>1; 50 if(check(mid)) {l=mid+1; ans=max(ans,mid);} 51 else r=mid-1; 52 } 53 while(q--) 54 { 55 x=read(); y=read(); a[x][y]=0; 56 for(int i=x;i<=n;++i) 57 for(int j=y;j<=m;++j) qz[i][j]--; 58 if(x>prex||x<prex-ans+1||y>prey||y<prey-ans+1) {printf("%d\n",ans); continue;} 59 if(check(ans)) {printf("%d\n",ans); continue;} 60 l=1; r=ans; ans=0; 61 while(l<=r) 62 { 63 int mid=(l+r)>>1; 64 if(check(mid)) {l=mid+1; ans=max(ans,mid);} 65 else r=mid-1; 66 } 67 printf("%d\n",ans); 68 } 69 return 0; 70 }
T3
是个非常恶心的树上期望DP?咕了