HDU4767_Sum Of Gcd
通过一个题目,学到了很多。
题意为给你n个数,每次询问i,j,答案为i,j间任取两数所有的取法gcd的和。
假设我们当前要看看这个区间有多少个数的gcd为x,最最原始的想法都是查询这个区间有多少个数为x的倍数。然后任取两个%&*¥#@!,但是有的gcd不是x,而是x的倍数。
这个问题这样来考虑,其实思想上是莫比乌斯反演。
假设当前我们有x个数是要求的现在的数y的倍数,那么所有的y的约数也肯定包含了这x个数。
所以我们可以当前要乘以的这个数不是x,而是一个f[x],显然x的所有的约数的函数和为x,这样就保证了求解的正确性。
同时想到了这里就会发现,所求的函数值与原题给的数据和各个数字的位置关系是没有关系的了,可以预处理。
最后看过各种,终于学到了,这个函数值就是欧拉函数值。 神坑啊。
还有就是这里的区间求解有一个小小的技巧。
区间分块处理,什么意思呢?
把区间排序,每次按照区间左端点所在的区进行排序,如果在同一区的话,就按右端点来排序,这样就保证了更新的复杂度为n*sqrt(n)。
真心受教了,不过鄙人还是觉得这种做法不太严谨,感觉如果是这个题目有极限数据的话,还是会T,不过确实比我想过的所有其他的想法都要优。
数论又一次被虐了。。。。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#define maxn 20002
typedef long long ll;
using namespace std; vector<int> g[maxn];
ll sum[maxn],ans;
int num[maxn],a[maxn],phi[maxn],t,n,m,Q,cas=,curl,curr; struct query{
int li,ri,pos;
}q[maxn]; bool cmp(query q1,query q2)
{
int l1=q1.li/m,l2=q2.li/m;
if (l1==l2) return q1.ri<q2.ri;
return q1.li<q2.li;
} void init()
{
for (int i=; i<maxn; i++)
for (int j=i; j<maxn; j+=i) g[j].push_back(i);
phi[]=;
for (int i=; i<maxn; i++)
{
if (phi[i]==) phi[i]=i;
else continue;
for (int j=i; j<maxn; j+=i)
{
if (phi[j]==) phi[j]=j;
phi[j]=phi[j]/i*(i-);
}
}
} void add(int x,int tag)
{
for (unsigned i=; i<g[x].size(); i++)
{
int k=g[x][i];
if (tag==-) num[k]--;
ans+=(ll)tag*num[k]*phi[k];
if (tag== ) num[k]++;
}
} void _process()
{
ans=;
memset(num,,sizeof num);
curl=q[].li,curr=q[].ri;
for (int i=curl; i<=curr; i++) add(a[i],);
sum[q[].pos]=ans;
for (int i=; i<=Q; i++)
{
while (curl<q[i].li) add(a[curl],-),curl++;
while (curr>q[i].ri) add(a[curr],-),curr--;
while (curl>q[i].li) add(a[--curl], );
while (curr<q[i].ri) add(a[++curr], );
sum[q[i].pos]=ans;
}
} int main()
{
init();
scanf("%d",&t);
while (t--)
{
scanf("%d",&n); m=(int)sqrt(n+0.5);
for (int i=; i<=n; i++) scanf("%d",&a[i]);
scanf("%d",&Q);
for (int i=; i<=Q; i++) scanf("%d%d",&q[i].li,&q[i].ri),q[i].pos=i;
sort(q+,q++Q,cmp);
_process();
printf("Case #%d:\n",++cas);
for (int i=; i<=Q; i++) printf("%I64d\n",sum[i]);
}
return ;
}
HDU4767_Sum Of Gcd的更多相关文章
- Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用
OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...
- iOS 多线程之GCD的使用
在iOS开发中,遇到耗时操作,我们经常用到多线程技术.Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,只需定义想要执行的任务,然后添加到适当的调度队列 ...
- 【swift】BlockOperation和GCD实用代码块
//BlockOperation // // ViewController.swift import UIKit class ViewController: UIViewController { @I ...
- 修改版: 小伙,多线程(GCD)看我就够了,骗你没好处!
多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能.具有这种能力的系 ...
- GCD的相关函数使用
GCD 是iOS多线程实现方案之一,非常常用 英文翻译过来就是伟大的中枢调度器,也有人戏称为是牛逼的中枢调度器 是苹果公司为多核的并行运算提出的解决方案 1.一次性函数 dispatch_once 顾 ...
- hdu1695 GCD(莫比乌斯反演)
题意:求(1,b)区间和(1,d)区间里面gcd(x, y) = k的数的对数(1<=x<=b , 1<= y <= d). 知识点: 莫比乌斯反演/*12*/ 线性筛求莫比乌 ...
- hdu2588 GCD (欧拉函数)
GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数. (文末有题) 知 ...
- BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】
2820: YY的GCD Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1624 Solved: 853[Submit][Status][Discu ...
- BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】
2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4436 Solved: 1957[Submit][Status][Discuss ...
随机推荐
- 2015526 《Java程序设计》实验二实验报告
2015526 <Java程序设计>实验二实验报告 一.单元测试和TDD 用程序解决问题时,要学会写以下三种代码: 伪代码 产品代码 测试代码 正确的顺序应为:伪代码(思路)→ 测试代码( ...
- vector的二维用法+前缀和
题目链接:https://codeforces.com/contest/1082/problem/C(C. Multi-Subject Competition) A multi-subject com ...
- Flutter系列博文链接
Flutter系列博文链接 ↓: Flutter基础篇: Flutter基础篇(1)-- 跨平台开发框架和工具集锦 Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法 Flutt ...
- 【Excel函数】如何在excle区分一列数字是否连续
需求:区分这批卡号,哪些在一个号段 数据源: 89860616090033685544898606160900336855518986061609003368556989860616090033685 ...
- springboot入门之一:环境搭建
springboot简介 springboot做为微服务的开发集合框架,有着天然的好处,它不像springmvc那样笨重繁杂,springmvc众多的配置使得开发人员很厌烦,为解决众多的配置带来的烦扰 ...
- JavaScript的数组和字符串应用
函数search实现在一个已排序的数字类型数组中查找指定数字的功能. 可以采用数组的内置方法,二分查找法等进行操作 //方法一 var search = function(arr,dst){ var ...
- Appium+python 自动发送邮件(1)(转)
(原文:https://www.cnblogs.com/fancy0158/p/10056091.html) SMTP:简单传输协议,实在Internet上传输Email的事实标准. Python的s ...
- 广东ACM省赛 E题
题意: 输入一个P 使得存在一个一个N大于等于P, 并且存在m 等于 m/n * (m-1)/(n-1)=1/2. 思路 此题可以利用佩尔方程求解, 也可以打表解决.本次我解决利用的是佩尔方程(其实也 ...
- #Ubuntu 18.04 安装tensorflow-gpu 1.9
参考 https://tensorflow.google.cn/install/install_linux http://nvidia.com/cuda http://developer.nvidia ...
- selenium--判断元素是否存在
# coding:utf-8from selenium import webdriverfrom selenium.webdriver.support.ui import WebDriverWaitf ...