NC230372. 和生蚝一起做乘法吧
描述
输入描述
第一行一个正整数,表示数据组数;
第二行到第行,每行两个正整数,表示区间。
输出描述
行,每行一个正整数表示所求的最小非零乘积,由于答案可能很大,只需要输出答案的值。
示例1
输入:
1 1 7
输出:
1512
C++ 解法, 执行用时: 890ms, 内存消耗: 5028K, 提交时间: 2021-11-24 20:37:25
#include<bits/stdc++.h> using namespace std; #define int long long const int mod = 1e9+7; int pow2[61]; int cal(int pos,int x) //[0,x]ÔÚµÚposλÉÏÓм¸¸ö1 { int zhouqi = pow2[pos]; return (x+1)/zhouqi*pow2[pos-1] + max(0LL,(x+1)%zhouqi - pow2[pos-1]); } struct node{ int cnt,id; }b[61]; bool cmp(node a,node b){ return a.cnt>b.cnt; } int qpow(int a,int k){ a%=mod; int ans=1; while(k) { if(k&1) ans = ans*a%mod; a=a*a%mod; k>>=1; } return ans; } signed main() { int t;scanf("%lld",&t); pow2[0]=1;for(int i=1;i<=60;i++) pow2[i]=pow2[i-1]*2; while(t--) { int l,r; scanf("%lld %lld",&l,&r); for(int i=1;i<=60;i++) b[i].cnt = cal(i,r)-cal(i,l-1),b[i].id=i; // for(int i=1;i<=60;i++) // { // printf("cnt[%lld]=%lld\n",i,cnt[i]); // } int mx_cnt = 0; for(int i=2;i<=60;i++) mx_cnt = max(mx_cnt,b[i].cnt); int n = r-l+1; b[1].cnt -= n-mx_cnt; sort(b+1,b+1+60,cmp); int now = 0,ans=1; for(int i=1;i<=60;i++) { if(b[i].cnt==0) continue; now += pow2[b[i].id-1]; ans = (ans * qpow(now,(b[i].cnt-b[i+1].cnt)) ) %mod; } printf("%lld\n",ans); } }