zoukankan      html  css  js  c++  java
  • [SDOI2014]数表

    SDOI2014 数表
    题意:已知

    [F(n) = sum_{d|n}{d} ]

    [sum_{i=1}^{n}sum_{j=1}^{m}{F(gcd(i,j))} mod 2^{31}, F(n) leq a ]

    做法:
    感谢 acfunction 大佬的题解 给我这个蒟蒻提供思路。
    我这只数学辣鸡居然写数学题解。
    先忽略 $ a $。

    [G(k) = sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j) == k] ]

    [G(k) = sum_{d=1}^{lfloorfrac{n}{k} floor}{mu(d)lfloorfrac{n}{id} floorlfloorfrac{m}{id} floor} ]

    [t = id ]

    [sum_{i=1}^{n}{F(i)G(i)} ]

    [= sum_{i=1}^{n}{F(i)}sum_{i|t}{mu(frac{t}{i})lfloorfrac{n}{t} floorlfloorfrac{m}{t} floor} ]

    [= sum_{t=1}^{n}lfloorfrac{n}{t} floorlfloorfrac{m}{t} floorsum_{i|t}{F(i)mu(frac{t}{i})} ]

    将所有询问离线,按 $ a $ 排序,边询问边加值,用树状数组维护前缀和再莫比乌斯反演即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned int ui;
    const int N=100010,mod=2147483647;
    int T;
    struct P {
    	int n,m,a,id;
    	friend bool operator<(P xx,P yy) { return xx.a<yy.a; }
    };P q[N];
    struct W {
    	int x,id;
    	friend bool operator<(W xx,W yy) { return xx.x<yy.x; }
    };W w[N];
    
    int f[N],mu[N],pri[N],lp=0,tr[N],ans[N];
    bool p[N];
    
    inline int Min(const int x,const int y) { return x<y? x:y; }
    void add(int x,ui w) { for(;x<=N-10;x+=(x&-x)) tr[x]+=w; }
    ui ask(int x) { ui sum=0; for(;x;x-=(x&-x)) sum+=tr[x]; return sum; }
    void init() {
    	for(int i=1;i<=N-10;i++) for(int j=i;j<=N-10;j+=i) f[j]+=(ui)i;
    	mu[1]=1;
    	for(int i=2;i<=N-10;i++) {
    		if(!p[i]) pri[++lp]=i,mu[i]=-1;
    		for(int j=1;pri[j]*i<=N-10;j++) {
    			p[pri[j]*i]=1; if(i%pri[j]==0) { mu[pri[j]*i]=0;break; }
    			mu[pri[j]*i]=-mu[i];
    		}
    	}
    }
    ui calc(int n,int m) {
    	ui sum=0; if(n>m) swap(n,m);
    	for(int l=1,r;l<=n;l=r+1) {
    		r=Min(n/(n/l),m/(m/l));
    		sum=sum+(n/l)*(m/l)*(ask(r)-ask(l-1));
    	}
    	return sum;
    }
    int main() {
    	init(),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].id=i;
    	for(int i=1;i<=N-10;i++) w[i].x=f[i],w[i].id=i;
    	sort(q+1,q+T+1),sort(w+1,w+N-10+1);
    	for(int i=1,j=0;i<=T;i++) {
    		while(j<N-10&&w[j+1].x<=q[i].a) {
    			++j;
    			for(int k=1;k*w[j].id<=N-10;k++)
    				add(k*w[j].id,w[j].x*mu[k]);
    		}
    		ans[q[i].id]=calc(q[i].n,q[i].m);
    	}
    	for(int i=1;i<=T;i++) printf("%d
    ",ans[i]&mod);
    	return 0;
    }
    
  • 相关阅读:
    获取DataGrid数据
    C# 分頁
    TCP 协议
    node fs对象
    ANSI转义码 改变输出的字体颜色
    异步流程控制模式
    node event对象
    js中的异常捕获 try{} catch{}(二)
    node require 文件查找的顺序
    node process全局对象
  • 原文地址:https://www.cnblogs.com/daniel14311531/p/10274076.html
Copyright © 2011-2022 走看看