zoukankan      html  css  js  c++  java
  • [bzoj 2693] jzptab & [bzoj 2154] Crash的数字表格 (莫比乌斯反演)

    题目描述

    TT组数据,给出NN,MM,求x=1Ny=1Mlim(x,y)sum_{x=1}^Nsum_{y=1}^M lim(x,y) ewline
    N,M<=10000000T<=10000N,M <= 10000000 ewline T<= 10000

    题目分析

    直接开始变换,假设N<M
    Ans=x=1Ny=1Mxy(x,y)=T=1N1Tx=1Ny=1Mxy[(x,y)==T]=T=1N1Tx=1NTy=1MTxyT2[(x,y)==1]=T=1NTx=1NTy=1MTxydx,dyμ(d)=d=1Nμ(d)T=1NTdxNTxdyMTy=d=1Nμ(d)T=1NTd2x=1NTdxy=1MTdy=d=1Nμ(d)T=1NTd2x=1NTdxy=1MTdyk=TdAns=k=1NTkμ(kT)kkTx=1Nkxy=1Mky=k=1NkTkμ(T)Tx=1Nkxy=1Mky Ans=sum_{x=1}^Nsum_{y=1}^M frac {xy}{(x,y)} ewline =sum_{T=1}^Nfrac 1Tsum_{x=1}^Nsum_{y=1}^Mxy[(x,y)==T] ewline =sum_{T=1}^Nfrac 1Tsum_{x=1}^{⌊frac NT⌋}sum_{y=1}^{⌊frac MT⌋}xyT^2[(x,y)==1] ewline =sum_{T=1}^NTsum_{x=1}^{⌊frac NT⌋}sum_{y=1}^{⌊frac MT⌋}xysum_{d|x,d|y}mu(d) ewline =sum_{d=1}^Nmu(d)sum_{T=1}^{N}Tsum_{d|x}^{⌊frac NT⌋}xsum_{d|y}^{⌊frac MT⌋}y ewline =sum_{d=1}^Nmu(d)sum_{T=1}^{N}Td^2sum_{x=1}^{⌊frac{⌊frac NT⌋}d⌋}xsum_{y=1}^{⌊frac{⌊frac MT⌋}d⌋}y ewline =sum_{d=1}^Nmu(d)sum_{T=1}^{N}Td^2sum_{x=1}^{⌊frac N{Td}⌋}xsum_{y=1}^{⌊frac M{Td}⌋}y ewline 此时令k=Td ewline Ans=sum_{k=1}^Nsum_{T|k}mu(⌊frac kT⌋)k⌊frac kT⌋sum_{x=1}^{⌊frac N{k}⌋}xsum_{y=1}^{⌊frac M{k}⌋}y ewline =sum_{k=1}^Nksum_{T|k}mu(T)Tsum_{x=1}^{⌊frac N{k}⌋}xsum_{y=1}^{⌊frac M{k}⌋}y ewline
    总算推完了…
    此时只需要Θ(N)Theta(N)线性筛出Tkμ(T)Tsum_{T|k}mu(T)T,然后处理kTkμ(T)Tksum_{T|k}mu(T)T的前缀和
    x=1Nkxy=1Mkysum_{x=1}^{⌊frac N{k}⌋}xsum_{y=1}^{⌊frac M{k}⌋}y可以Θ(1)Theta(1)
    利用整除分块优化,时间复杂度为Θ(N+TN)Theta(N+Tsqrt N)

    AC code([bzoj 2693] jzptab)
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN = 10000005, mod = 1e8+9;
    int N, M;
    namespace Mobius
    {
    	int mu[MAXN], Prime[MAXN], cnt;
    	bool IsnotPrime[MAXN];
    	int sum[MAXN];
    	void init()
    	{
    		sum[1] = 1;
    		for(int i = 2; i <= MAXN-5; i++)
    		{
    			if(!IsnotPrime[i]) Prime[++cnt] = i, sum[i] = 1-i;
    			for(int j = 1; j <= cnt && i * Prime[j] <= MAXN-5; j++)
    			{
    				IsnotPrime[i * Prime[j]] = 1;
    				if(i % Prime[j] == 0) { sum[i * Prime[j]] = sum[i]; break; }
    				sum[i * Prime[j]] = 1ll * sum[i] * (1 - Prime[j]) % mod;
    			}
    		}
    		for(int i = 1; i <= MAXN-5; i++)//前缀和
    			sum[i] = (sum[i-1] + 1ll*sum[i]*i%mod) % mod;
    	}
    	int Sum(int N, int M)
    	{
    		return ((1ll*N*(N+1)/2) % mod) * ((1ll*M*(M+1)/2) % mod) % mod;
    	}
    	int calc(int N, int M)
    	{
    		int ret = 0;
    		for(int i = 1, j; i <= N; i=j+1)//整除分块
    		{
    			j = min(N/(N/i), M/(M/i));
    			ret = (ret + 1ll * (sum[j] - sum[i-1]) % mod * Sum(N/i, M/i) % mod) % mod;
    		}
    		return ret;
    	}
    }
    using namespace Mobius;
    int main ()
    {
    	int T; init();
    	scanf("%d", &T);
    	while(T--)
    	{
    		scanf("%d%d", &N, &M); if(N > M) swap(N, M);
    		printf("%d
    ", (calc(N, M) + mod) % mod);
    	}
    }
    
    AC code([bzoj 2154] Crash的数字表格)

    这道题有个恶心的地方,不能用MaxnMaxn来预处理,否则会TLETLE,要读入NN,MM后再O(N)O(N)处理

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAXN = 10000005, mod = 20101009;
    int N, M;
    namespace Mobius
    {
    	int mu[MAXN], Prime[MAXN], cnt;
    	bool IsnotPrime[MAXN];
    	int sum[MAXN];
    	void init()
    	{
    		sum[1] = 1;
    		for(int i = 2; i <= N; i++)
    		{
    			if(!IsnotPrime[i]) Prime[++cnt] = i, sum[i] = 1-i;
    			for(int j = 1; j <= cnt && i * Prime[j] <= N; j++)
    			{
    				IsnotPrime[i * Prime[j]] = 1;
    				if(i % Prime[j] == 0) { sum[i * Prime[j]] = sum[i]; break; }
    				sum[i * Prime[j]] = 1ll * sum[i] * (1 - Prime[j]) % mod;
    			}
    		}
    		for(int i = 1; i <= N; i++)
    			sum[i] = (sum[i-1] + 1ll*sum[i]*i%mod) % mod;
    	}
    	int Sum(int N, int M)
    	{
    		return ((1ll*N*(N+1)/2) % mod) * ((1ll*M*(M+1)/2) % mod) % mod;
    	}
    	int calc(int N, int M)
    	{
    		int ret = 0;
    		for(int i = 1, j; i <= N; i=j+1)
    		{
    			j = min(N/(N/i), M/(M/i));
    			ret = (ret + 1ll * (sum[j] - sum[i-1]) % mod * Sum(N/i, M/i) % mod) % mod;
    		}
    		return ret;
    	}
    }
    using namespace Mobius;
    int main ()
    {
    	scanf("%d%d", &N, &M); if(N > M) swap(N, M); init();
    	printf("%d
    ", (calc(N, M) + mod) % mod);
    }
    
  • 相关阅读:
    Django 框架篇(四) : 视图(view)详解 及 路由系统(url)
    Django 框架篇(三) : Django之模板
    Django 框架篇(二) : 创建APP之视图函数; model(模型)系统操作数据库之ORM操作;
    Django 框架篇: 一. Django介绍; 二. 安装; 三. 创建项目;
    212
    redux:applyMiddleware源码解读
    react 反模式——不使用jsx动态显示异步组件
    angular 动态组件类型
    webpack2-webpack.config.js配置
    tdd:(react + mocha)环境配置
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039466.html
Copyright © 2011-2022 走看看