题解用的分形的思想,但是我感觉看不太出来……emmm
还好找到了有别的做法QOQ
这里收藏了一个求lowbit的方法,因为从来没写过树状数组所以觉得很有意思!
ll lowbit(x){
return x&(-x);//大佬可太秀了
}
题目的做法:
1.用log2(n)方的复杂度找到a[n]对应的数字
2.根据每个数字出现的次数的规律统计也是log的复杂度
3.被卡了一发时间,刚开始的时候二分的左右边界是1和1e18,盲目改成1和x交了一发就过了
更详细看大佬博客园!
#include<iostream>
#define ll long long
#define MOD 1000000007
#define INV2 500000004
using namespace std;
ll find(ll x){
if (x==1) return 1;
else if (x==0) return 0;
else return find(x/2)+x;
}
ll get(ll x){
ll l=1,r=x+2;
while (l!=r){
ll m=(l+r)/2;
if (find(m)>=x){
r=m;
}
else{
l=m+1;
}
}
return l;
}
ll getans(ll n, ll top){
ll nx=find(top-1);
ll ans=(n-nx)%MOD*top%MOD;
top--;
n=nx;
ll i=2,tot,j=1,v;
while (tot=(top+i/2)/i){
tot%=MOD;
ans=(ans+(i%MOD+(tot-1)*(i%MOD))%MOD*tot%MOD*INV2%MOD*j%MOD)%MOD;
i*=2;
j++;
}
return ans;
}
int main(){
ll T,n;
scanf("%lld",&T);
while (T--){
scanf("%lld",&n);
n--;
ll top=get(n);
printf("%lld\n",getans(n,top)+1);
}
return 0;
}
/*
1
5
1000000000000000000
*/