T1
题解:枚举两边长。。会多出来一小截。。XJB统计一下
#include<cmath> #include<cstdio> #include<iostream> using namespace std; int s2k(int k){ return k*(k-1)/2; } int ans=0; int main(){ freopen("rectangle.in","r",stdin); freopen("rectangle.out","w",stdout); int n,m,k; scanf("%d %d %d",&n,&m,&k); if(n>m)swap(n,m); int a=min((int)sqrt((double)k),n); for(int i=2;i<=a;i++){ int b=min(m,k/i); if(k<b*(i+1)){ if(b<m) ans=max(ans,s2k(i)*s2k(b)+s2k(k-i*b)*b); else ans=max(ans,s2k(i)*s2k(b)+s2k(k-i*b)*i); } } cout<<ans<<endl; return 0; }
T2
题解:然后两个前缀和相减就能算了
用矩阵快速幂计算
#include<cstdio> #include<string.h> #include<iostream> #define mod 10000 using namespace std; int f[1000005]; struct mat{ int a[2][2]; int*operator [](int _a){ return a[_a]; } }; mat c,sple; mat mul(mat a,mat b){ mat t; memset(t.a,0,sizeof(t.a)); for(int i=0;i<2;i++)for(int j=0;j<2;j++)for(int k=0;k<2;k++)t[i][j]=(t[i][j]+a[i][k]*b[k][j])%10000; return t; } int intp(int a,int n){ if(!n)return 1; int _p=intp(a,n/2); return _p*_p*((n&1)?a:1); } mat matp(mat a,long long n){ if(!n)return c; mat t=matp(a,n/2); return mul(mul(t,t),(n&1ll?a:c)); } int getfib(long long n){ mat a; a[0][0]=1;a[0][1]=1; a[1][0]=1;a[1][1]=0; for(int i=0;i<2;i++)for(int j=0;j<2;j++)c[i][j]=(i==j); mat ans=matp(a,n); //printf("(%d %d %d %d) ",ans[0][0],ans[0][1],ans[1][0],ans[1][1]); return ans[0][1]; } int main(){ freopen("fibonacci.in","r",stdin); freopen("fibonacci.out","w",stdout); int T;cin>>T; //f[1]=1;f[2]=1;for(int i=3;i<=1000;i++)f[i]=(f[i-1]+f[i-2])%mod; //for(int i=1;i<=1000;i++)printf("%d ",f[i]); while(T--){ //f(y+2)-f(x+1)-2 int x,y;scanf("%d %d",&x,&y); printf("%d ",((getfib((long long)y+2)-getfib((long long)x+1))%mod+mod)%mod); //printf("force ans=%d ",(f[y+2]-f[x+1]+mod)%mod); } return 0; }