唯一分解定理
先分解面积,然后除2,再减去面积%长度==0的情况,注意毯子不能是正方形

#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-7; const int N=1000000+10,maxn=500+100,inf=0x3f3f3f; bool vis[N]; ll prime[N],cnt; void getprime() { cnt=0; memset(vis,0,sizeof vis); for(int i=2;i<N;i++) { if(!vis[i]) { prime[cnt++]=i; for(int j=2*i;j<N;j+=i) vis[j]=1; } } } ll getnum(ll x) { if(x==0)return 0; ll ans=1; for(ll i=0; i<cnt&&prime[i]*prime[i]<=x; i++) { ll k=1; while(x%prime[i]==0){ x/=prime[i]; k++; } ans*=k; } if(x!=1)ans*=2; ans/=2; return ans; } int main() { /* ios::sync_with_stdio(false); cin.tie(0);*/ getprime(); int t,cnt=0; scanf("%d",&t); while(t--){ ll a,b; scanf("%lld%lld",&a,&b); if(b*b>=a) { printf("Case %d: %lld ",++cnt,0); continue; } ll ans=getnum(a); for(ll i=1;i<b;i++) if(a%i==0) ans--; printf("Case %d: %lld ",++cnt,ans); } return 0; } /********************* 2 10 2 12 2 *********************/