题解:P10855 【MX-X2-T4】「Cfz Round 4」Gcd with Xor
题意
求 对 取模的结果。
分析
既然 的做法已经被说烂了,那我就来一个更烂的 的做法。
令 二进制下的最高位为 ,。
直接开始推式子, 显然拆不开,考虑枚举它:
多出来的 是 的情况。
接着考虑处理条件 ,由于 ,所以 。
不放设 与 第 位均相同,第 位时 ,那么就有 且 。也就是说当且仅当 , 为 的最高位时 !于是令 表示 , 表示 ,那么答案为:
令 ,显然这个东西可以在 树上预处理出来,均摊后总复杂度为 。
接着对 进行莫比乌斯反演:
这部分计算的复杂度是 的,总复杂度大概为 ,看起来十分过不了,然而给出的数的值是连续的,所以其在 中的分布是均匀的,只要大力卡常就能在单点大约 内通过。别缩短时限啊qwq
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
void write(ll x){
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
}
const int N=(1<<18)+10,M=19;
const ll mod=1e9+7;
int T,n,k,Log[N],tn;
ll dk[N],f[N];
ll qmi(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;b>>=1;
}
return ans;
}
vector<int>U[M],V[M],sep[N],facu[N],facv[N];
int m,pri[N],vis[N],miu[N];
void init(int n){
vis[1]=1;miu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
vis[i]=pri[++m]=i;
miu[i]=-1;
}
for(int j=1;j<=m&&i*pri[j]<=n;j++){
vis[i*pri[j]]=pri[j];
miu[i*pri[j]]=miu[i]*-1;
if(i%pri[j]==0){
miu[i*pri[j]]=0;break;
}
}
}
}
int find(int d,int x,int l,int r){
if(facu[d][r]<x)return r+1;
int mid;
while(l<r){
mid=(l+r)>>1;
if(facu[d][mid]>=x)r=mid;
else l=mid+1;
}
return l;
}
struct Trie{
int ch[N*20][2],tot=1,p;
int sz[N*20];
void change(register int x,int v){
sz[p=1]+=v;
for(int i=tn,c;i>=0;i--){
c=(x>>i)&1;
if(!ch[p][c])ch[p][c]=++tot;
p=ch[p][c];
sz[p]+=v;
}
}
void clear(){
for(register int i=1;i<=tot;i++)ch[i][0]=ch[i][1]=0;
tot=1;
}
ll ask(int p,int t,int d,int ms,int l,int r){
if(!p||!sz[p]||l>r)return 0;
if(t==-1){
return 1ll*sz[p]*(r-l+1);
}
ll ans=0;
int mpos=find(d,ms|(1<<t),l,r);
if((n>>t)&1){
if(l<=mpos-1){
ans+=1ll*sz[ch[p][0]]*(mpos-l);
ans+=ask(ch[p][1],t-1,d,ms,l,mpos-1);
}
if(mpos<=r){
ans+=1ll*sz[ch[p][1]]*(r-mpos+1);
ans+=ask(ch[p][0],t-1,d,ms|(1<<t),mpos,r);
}
}
else{
ans+=ask(ch[p][0],t-1,d,ms,l,mpos-1);
ans+=ask(ch[p][1],t-1,d,ms|(1<<t),mpos,r);
}
return ans;
}
}tr;
void solve(){
tn=Log[n];int n2=(1<<tn+1);
for(register int t=0;t<=tn;t++){
U[t].clear();V[t].clear();
for(register int i=1;i<=n;i++){
if(!((i>>t)&1))
U[t].push_back(i);
}
}
for(register int i=1,j,tc;i<n2;i++){
j=i;tc=-1;
while(j)j>>=1,tc++;
V[tc].push_back(i);
}
for(register int i=1;i<=n;i++){
dk[i]=qmi(i,k);
f[i]=0;
}
for(register int t=0;t<=tn;t++){
for(register int i=1;i<=n;i++){
facu[i].clear();
facv[i].clear();
}
for(register auto x:U[t]){
for(register auto p:sep[x])
facu[p].push_back(x);
}
for(register auto x:V[t]){
for(register auto p:sep[x])
facv[p].push_back(x);
}
for(register int d=1;d<=n;d++){
for(register auto x:facv[d])
tr.change(x,1);
f[d]=(f[d]+tr.ask(1,tn,d,0,0,facu[d].size()-1))%mod;
for(register auto x:facv[d])
tr.change(x,-1);
}
}
ll ans=0,res;
for(register int d=1;d<=n;d++){
res=1;
for(register int c=1;c<=n/d;c++)
res+=miu[c]*f[c*d];
ans=(ans+dk[d]*res%mod);
}
ans=(ans%mod+mod)%mod;
write(ans);putchar('\n');
}
int main(){
T=read();
Log[0]=-1;
for(register int i=1;i<N;i++)Log[i]=Log[i>>1]+1;
for(register int i=1;i<N;i++){
for(register int j=1;j*j<=i;j++){
if(i%j==0){
sep[i].push_back(j);
if(j*j!=i)
sep[i].push_back(i/j);
}
}
}
init(N-5);
while(T--){
tr.clear();
n=read();k=read();
solve();
}
return 0;
}

浙公网安备 33010602011771号