#4728. 问题求解
题目描述
求 \sum\limits_{i=1}^n{(im\land m) \bmod (10^9+7)},其中 \land 指按位与。
题解
哎我太蠢了一直往 \text{dp} 的方向想。
下面的除法都是下取整(特殊的是上取整,会说明)(我不会打qwq)
考虑到当 m 的第 x 位为 1 的时候,求有多少个 i 使得 im 的第 x 位也为 1 ,那其实可以看成 \frac{im}{2^x} 是奇数的个数,也就是 \frac{im}{2^x}-2\times \frac{im}{2^{x+1}} ,这个值是 0/1 ,于是我们考虑快速求 \sum_{i=0}^n\frac{im}{2^x} 。
get到新知识:类欧几里得!
我们可以设 f(a,b,c,n)=\sum_{i=0}^n\frac{ai+b}{c} ,然后我们分讨一下
1. a=0
那就是 (n+1) \times \frac{b}{c}
2. a<c 且 b<c
我们可以推下式子:
f(a,b,c,n)=\sum_{i=0}^n\frac{ai+b}{c}
=\sum_{i=0}^n\sum_{j=0}^{\frac{ai+b}{c}-1}1
=\sum_{j=0}^{\frac{an+b}{c}-1}\sum_{i=0}^n[j<\frac{ai+b}{c}]
=\sum_{j=0}^{\frac{an+b}{c}-1}\sum_{i=0}^n[j<\frac{ai+b-c+1}{c}]
☆(\frac{ai+b-c+1}{c}是上取整)
=\sum_{j=0}^{\frac{an+b}{c}-1}\sum_{i=0}^n[cj<ai+b-c+1]
=\sum_{j=0}^{\frac{an+b}{c}-1}n-\frac{cj+c-b-1}{a}
=n\times \frac{an+b}{c}-f(c,c-b-1,a,\frac{ai+b}{c}-1)
3. 剩下的情况
f(a,b,c,n)=\sum_{i=0}^n\frac{ai+b}{c}
=\sum_{i=0}^n\frac{(a\%c)i+(b\%c)}{c}+i\times \frac{a}{c}+\frac{b}{c}
=f(a\%c,b\%c,c,n)+\frac{n(n+1)}{2}\frac{a}{c}+(n+1)\times \frac{b}{c}
于是这部分的效率就是 log 的,所以总效率是 O(log^2) 的
代码
#include <bits/stdc++.h> #define LL long long using namespace std; const int P=1e9+7; LL n,m;int s; int X(int x){return x>=P?x-P:x;} int f(LL a,LL b,LL c,LL d){ if (a==0) return (d+1)%P*((b/c)%P)%P; if (a<c && b<c){ LL x=((__int128)a*d+b)/c; return X(d%P*(x%P)%P-f(c,c-b-1,a,x-1)+P); } return X(X(f(a%c,b%c,c,d)+d%P*((d+1)%P)%P*((P+1)>>1)%P*((a/c)%P)%P)+(d+1)%P*((b/c)%P)%P); } int main(){ cin>>n>>m; for (int u,v=0,i=39;~i;i--){ u=v;v=f(m,0,1ll<<i,n); if (m&(1ll<<i)) s=X(s+1ll*X(v-X(u+u)+P)*((1ll<<i)%P)%P); } cout<<s<<endl;return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步