• BZOJ:3529: [Sdoi2014]数表


    题解:

    反演,按a从小到大排序,依次加入符合题意的f(d)值;

    用树状数组维护前缀和

    注意:

      取模时做差注意负数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long Lint;
    const int maxQ=20009;
    const int maxn=100009;
    const Lint mm=(1LL<<31);
    
    int T;
    Lint ans[maxn];
    struct questions{
    	int n,m,a,idx;
    }q[maxQ];
    int cmp(const questions &tmp1,const questions &tmp2){
    	return tmp1.a<tmp2.a;
    }
    
    Lint f[maxn];
    Lint g[maxn];
    int d[maxn];
    int cmp2(const int &tmp1,const int &tmp2){
    	if(f[tmp1]<f[tmp2])return 1;
    	else return 0;
    }
    
    int vis[maxn]={0};
    int prime[maxn],cntprime;
    int mu[maxn];
    int r[maxn];
    int prepro(){
    	vis[1]=1;mu[1]=1;
    	for(int i=2;i<=100000;++i){
    		if(!vis[i]){
    			prime[++cntprime]=i;
    			mu[i]=-1;
    		}
    		for(int j=1;j<=cntprime&&i*prime[j]<=100000;++j){
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0){
    				mu[i*prime[j]]=0;
    				break;
    			}
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for(int i=2;i<=100000;++i)mu[i]+=mu[i-1];
    	for(int d=1;d<=100000;++d){
    		for(int k=1;k*d<=100000;++k){
    			f[d*k]=(f[d*k]+d)%mm;
    		}
    	}
    	for(int i=1;i<=100000;++i)r[i]=i;
    	sort(r+1,r+1+100000,cmp2);
    }
    
    Lint c[maxn];	
    inline int lowbit(int x){
    	return x&(-x);
    }
    int add(int x,Lint val){
    	while(x<=100000){
    		c[x]=(c[x]+val)%mm;
    		x+=lowbit(x);
    	}
    }
    Lint query(int x){
    	Lint ret=0;
    	while(x){
    		ret=(ret+c[x])%mm;
    		x-=lowbit(x);
    	}
    	return ret;
    }
    
    int minit(){
    	memset(f,0,sizeof(f));
    	memset(g,0,sizeof(g));
    	memset(c,0,sizeof(c));
    	cntprime=0;
    }
    
    int main(){
    	minit();
    	prepro();
    	
    	scanf("%d",&T);
    	for(int i=1;i<=T;++i){
    		scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a);
    		q[i].idx=i;
    	}
    	sort(q+1,q+1+T,cmp);
    	
    	int head=0;
    	for(int i=1;i<=T;++i){
    		while((head<100000)&&(f[r[head+1]]<=q[i].a)){
    			int v=r[++head];
    			for(int k=1;k*v<=100000;++k){
    				add(k*v,f[v]*(mu[k]-mu[k-1]));
    			}
    		}
    		int n=q[i].n;
    		int m=q[i].m;
    		int a=q[i].a;
    		if(n>m)swap(n,m);
    		Lint ret=0;
    		int last;
    		for(int j=1;j<=n;j=last+1){
    			last=min(n/(n/j),m/(m/j));
    			ret=ret+(query(last)-query(j-1)+mm)*1LL*(n/j)*(m/j);
    			ret=ret%mm;
    		}
    		ans[q[i].idx]=ret;
    	}
    	
    	for(int i=1;i<=T;++i){
    		printf("%lld
    ",ans[i]);
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    Hash碰撞 & 拒绝服务漏洞
    Java: 在不同windows主题下,JFrame窗口设置最佳高度的解决方案
    java: 关于从jar中读取资源遇到的问题getClass().getResource(...)
    Windows 服务程序、窗口界面、桌面交互、与远程桌面
    MySQL用户与权限管理
    Linux 用户与用户组
    书单整理
    2013年个人工作与学习总结
    Raphaël.js学习笔记
    Ant学习笔记(2) 在Eclipse中使用Ant
  • 原文地址:https://www.cnblogs.com/zzyer/p/8179434.html
Copyright © 2020-2023  润新知