factor:
题目大意:求(ax+by)^k展开后x^n*y^m的系数%10007。n,m,k<=1e3,a,b<=1e6.
题解:
裸的二项式定理,得到x^n*y^m的系数为
an
bm
Cmk
,组合数取模可以用逆元也可以用杨辉三角形。时间复杂度:O(k^2)(杨辉三角形)或O(k log 10007)(逆元),空间复杂度:O(k^2)(杨辉三角形)或O(1)(逆元)。
代码给的是杨辉三角形。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
int a,b,k,n,m,i,j,f[1010][1010];
int ksm(int x,int y){
int ans=1;
for(;y;y>>=1){
if(y&1)ans=((long long)ans*x)%10007;
x=((long long)x*x)%10007;
}
return ans;
}
int main(){
freopen("factor.in","r",stdin);
freopen("factor.out","w",stdout);
scanf("%d%d%d%d%d",&a,&b,&k,&n,&m);
f[0][0]=1;
for(i=1;i<=k;i++)
for(j=0;j<=k;j++)
f[i][j]=(f[i-1][j]+f[i-1][j-1])%10007;
printf("%d",(((ksm(a,n)*ksm(b,m))%10007)*f[k][m])%10007);
return 0;
}
qc:
突然想骗访问量……
http://blog.csdn.net/PbTfcLx/article/details/50493189
这是我以前写的题解……这里贴C++的代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
int n,m,i,mid,li=1e7,ri,l[200010],r[200010],w[200010],v[200010],a[200010];
long long S,j,s[200010],ans=1e18;
long long pd(int x){
long long ans=0;
memset(a,0,sizeof(a));
memset(s,0,sizeof(s));
for(int i=1;i<=n;i++)
if(w[i]>=x)s[i]=s[i-1]+v[i],a[i]=a[i-1]+1;
else s[i]=s[i-1],a[i]=a[i-1];
for(int i=1;i<=m;i++)
ans+=(s[r[i]]-s[l[i]-1])*(a[r[i]]-a[l[i]-1]);
return ans;
}
int main(){
freopen("qc.in","r",stdin);
freopen("qc.out","w",stdout);
scanf("%d%d%I64d",&n,&m,&S);
for(i=1;i<=n;i++)scanf("%d%d",&w[i],&v[i]),ri=max(ri,w[i]),li=min(li,w[i]);
for(i=1;i<=m;i++)scanf("%d%d",&l[i],&r[i]);
while(li<=ri){
mid=(li+ri)>>1;
j=pd(mid);
ans=min(ans,abs(j-S));
if(j>S)li=mid+1;
else ri=mid-1;
}
printf("%I64d",ans);
return 0;
}
bus:
嗯……以前我也写过题解……
http://blog.csdn.net/PbTfcLx/article/details/50493190
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
struct node{
int la,xia,d;
}c[1010];
int n,m,k,a[10010],b[10010],t[10010],i,j,d[1010],maxn,maxi,ans,dat[1010];
int main(){
freopen("bus.in","r",stdin);
freopen("bus.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<n;i++)scanf("%d",&c[i].d);
for(i=1;i<=m;i++){
scanf("%d%d%d",&t[i],&a[i],&b[i]);
c[a[i]].la=max(c[a[i]].la,t[i]);
c[b[i]].xia++;
}
for(i=2;i<=n;i++)d[i]=max(c[i-1].la,d[i-1])+c[i-1].d;
for(;k;k--){
maxn=maxi=0;
for(i=n;i;i--)
if(c[i].la<d[i])dat[i]=dat[i+1]+c[i].xia;
else dat[i]=c[i].xia;
for(i=1;i<=n;i++)
if(dat[i]>maxn&&c[i-1].d>0)maxn=dat[i],maxi=i;
c[maxi-1].d--;
for(i=maxi;i<=n;i++)d[i]=max(d[i-1],c[i-1].la)+c[i-1].d;
}
for(i=1;i<=m;i++)ans+=d[b[i]]-t[i];
printf("%d",ans);
return 0;
}
flow:
题目大意:一个n*m的矩阵,第一行可以建蓄水厂,最后一行的每个格子都需要有水,每个格子可以可以由它旁边的海拔比它高的有水的格子输水过来,求是否能将最后一行的每个格子都输到水,若可以输出最少的蓄水厂数,若不行,输出不能输到水的格子数。n,m<=500.
题解:
我们需要先判断是否最后一行的每个格子全都能覆盖到……
这个只需要搜一遍就好了,还可以记忆化,就保证了复杂度为O(nm),对于某个格子,我们搜到它能流向的格子,然后如果该格子为最后一行的,我们就cnt++,最终只需判断cnt是否=n即可。
如果cnt
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
struct node{
int l,r;
bool friend operator <(node a,node b){
if(a.l==b.l)return a.r>b.r;
return a.l<b.l;
}
}a[510][510];
int n,m,i,j,cnt,l,r,maxn,ans=1000,h[510][510],ff[510],dx[4]={0,1,-1,0},dy[4]={1,0,0,-1};
bool f[510][510],flag;
void dfs(int x,int y){
if(x==n){
a[x][y].l=min(a[x][y].l,y);
a[x][y].r=max(a[x][y].r,y);
}
f[x][y]=1;
for(int i=0;i<4;i++)
if(x+dx[i]>0&&x+dx[i]<=n&&y+dy[i]>0&&y+dy[i]<=m){
int fx=x+dx[i],fy=y+dy[i];
if(h[x][y]>h[fx][fy]){
if(!f[fx][fy])dfs(fx,fy),a[x][y].l=min(a[x][y].l,a[fx][fy].l),a[x][y].r=max(a[x][y].r,a[fx][fy].r);
else a[x][y].l=min(a[x][y].l,a[fx][fy].l),a[x][y].r=max(a[x][y].r,a[fx][fy].r);
}
}
}
int main(){
int __size__ = 20 << 20;
char *__p__ = (char*)malloc(__size__) + __size__;
__asm__("movl %0, %%esp\n" :: "r"(__p__));
freopen("flow.in","r",stdin);
freopen("flow.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)a[i][j].l=1000;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)scanf("%d",&h[i][j]);
for(i=1;i<=m;i++)
if(!f[1][i])dfs(1,i);
flag=1;
for(i=1;i<=m;i++)
if(!f[n][i]){
flag=0;
cnt++;
}
if(!flag){
puts("0");
printf("%d",cnt);
}
else{
puts("1");
sort(a[1]+1,a[1]+1+m);
memset(ff,1,sizeof(ff));
ff[1]=1;
for(i=2;i<=m;i++){
maxn=1000;
for(j=1;j<i;j++)
if(a[1][j].r>a[1][i].l-2)maxn=min(maxn,ff[j]);
ff[i]=maxn+1;
}
for(i=1;i<=m;i++)
if(a[1][i].r==m)ans=min(ans,ff[i]);
printf("%d",ans);
}
return 0;
}