hdu 5726 GCD GCD+线段树+区间预处理+map
GCD
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2530 Accepted Submission(s): 895
The first line of each case contains a number N, denoting the number of integers.
The second line contains N integers, a1,...,an(0<ai≤1000,000,000).
The third line contains a number Q, denoting the number of queries.
For the next Q lines, i-th line contains two number , stand for the li,ri, stand for the i-th queries.
For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,...,ar) and the second number stands for the number of pairs(l′,r′) such that gcd(al′,al′+1,...,ar′) equal gcd(al,al+1,...,ar).
5
1 2 4 6 7
4
1 5
2 4
3 4
4 4
1 8
2 4
2 4
6 1
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MM(a,b) memset(a,b,sizeof(a));
#define inf 0x7f7f7f7f
#define FOR(i,n) for(int i=1;i<=n;i++)
#define CT continue;
#define PF printf
#define SC scanf
const int mod=1000000007;
const int N=3*1e5+10; int n,a[N],l[N],r[N]; struct node{
int l,r;
ll sum,lazy;
int gcdn;
void fun(ll v){
this->lazy+=v;
sum+=v*(r-l+1);
}
int mid(){
return (l+r)>>1;
}
}tree[4*N],tree2[4*N]; int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
} void build(int k,int l,int r)
{
tree[k].l=l;tree[k].r=r;
if(l==r)
{
tree[k].gcdn=a[l];
return;
}
int mid=(l+r)>>1;
build(2*k,l,mid);
build(2*k+1,mid+1,r);
tree[k].gcdn=gcd(tree[2*k].gcdn,tree[2*k+1].gcdn);
} ll query(int k,int l,int r)
{
if(l<=tree[k].l&&tree[k].r<=r) return tree[k].gcdn;
else {
int mid=tree[k].mid();
int gcdk=0;
if(l<=mid) gcdk=query(2*k,l,r);
if(r>mid) gcdk=gcdk==0?query(2*k+1,l,r):gcd(gcdk,query(2*k+1,l,r));
return gcdk;
}
} map<int,ll> tmp,tmpnext,ans;
map<int,ll>::iterator it; void init()
{
tmp.clear();ans.clear();
for(int i=1;i<=n;i++)
{
tmpnext.clear();
tmpnext[a[i]]++;
for(it=tmp.begin();it!=tmp.end();++it)
{
int k=gcd(a[i],it->first);
tmpnext[k]+=it->second;
}
for(it=tmpnext.begin();it!=tmpnext.end();it++)
ans[it->first]+=it->second;
tmp=tmpnext;
}
} int main()
{
int cas,q,kk=0;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
init();
scanf("%d",&q);
for(int i=1;i<=q;i++) scanf("%d%d",&l[i],&r[i]);
printf("Case #%d:\n",++kk);
for(int i=1;i<=q;i++)
{
int k=query(1,l[i],r[i]);
printf("%d %lld\n",k,ans[k]);
}
}
return 0;
}
我们注意观察gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar),当l固定不动的时候,r=l...nr=l...n时,我们可以容易的发现,随着rr的増大,gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar)是递减的,同时gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar)最多 有log\ 1000,000,000log 1000,000,000个不同的值,为什么呢?因为a_{l}al最多也就有log\ 1000,000,000log 1000,000,000个质因数
所以我们可以在log级别的时间处理出所有的以L开头的左区间的gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar)
那么我们就可以在n\ log\ 1000,000,000n log 1000,000,000的时间内预处理出所有的gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar)
然后我们可以用一个map来记录,gcd值为key的有多少个 然后我们就可以对于每个询问只需要查询
对应gcd(a_{l},a_{l+1},...,a_{r})gcd(al,al+1,...,ar)为多少,然后再在map 里面查找对应答案即可.
错因分析:1.没能正确发现对于一个a(<=1e9)他的质因数个数是loga级别的,因为比如2*2*3*5.....=a,则左边至多loga个元素,
hdu 5726 GCD GCD+线段树+区间预处理+map的更多相关文章
- HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举
HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...
- hdu 1540 Tunnel Warfare(线段树区间统计)
Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- Master of GCD 【线段树区间更新 || 差分】
Master of GCD 时间限制: 1 Sec 内存限制: 128 MB 提交: 670 解决: 112 [提交] [状态] [命题人:admin] 题目描述 Hakase has n num ...
- upc组队赛2 Master of GCD 【线段树区间更新 || 差分】
Master of GCD 题目描述 Hakase has n numbers in a line. At fi rst, they are all equal to 1. Besides, Haka ...
- HDU 4902 Nice boat --线段树(区间更新)
题意:给一个数字序列,第一类操作是将[l,r]内的数全赋为x ,第二类操作是将[l,r]中大于x的数赋为该数与x的gcd,若干操作后输出整个序列. 解法: 本题线段树要维护的最重要的东西就是一个区间内 ...
- HDU 3577 Fast Arrangement (线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577 题意不好理解,给你数字k表示这里车最多同时坐k个人,然后有q个询问,每个询问是每个人的上车和下车 ...
- hdu 3397 Sequence operation (线段树 区间合并 多重标记)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意: 给你一串01串,有5种操作 0. 区间全部变为0 1.区间全部变为1 2.区间异或 3.询问 ...
- hdu 1698+poj 3468 (线段树 区间更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1698 这个题意翻译起来有点猥琐啊,还是和谐一点吧 和涂颜色差不多,区间初始都为1,然后操作都是将x到y改为z,注 ...
- SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)
题意 : 给出一段n个数的序列,接下来给出m个询问,询问的内容SPOJ是(L, R)这个区间内不同的数的个数,HDU是不同数的和 分析 : 一个经典的问题,思路是将所有问询区间存起来,然后按右端点排序 ...
随机推荐
- Java 线程控制
一.线程控制 和线程相关的操作都定义在Thread类中,但在运行时可以获得线程执行环境的信息.比如查看可用的处理器数目(这也行?): public class RunTimeTest { public ...
- 手把手教你搭建FastDFS集群(上)
手把手教你搭建FastDFS集群(上) 本文链接:https://blog.csdn.net/u012453843/article/details/68957209 FastDFS是一个 ...
- 【原创】运维基础之Amplify
官方:https://www.nginx.com/products/nginx-amplify/ NGINX Amplify is a SaaS‑based monitoring tool for t ...
- 关键词提取算法TF-IDF与TextRank
一.前言 随着互联网的发展,数据的海量增长使得文本信息的分析与处理需求日益突显,而文本处理工作中关键词提取是基础工作之一. TF-IDF与TextRank是经典的关键词提取算法,需要掌握. 二.TF- ...
- Redis教程(REmote DIctionary Server)——一个高性能的key-value数据库
redis(REmote DIctionary Server)是什么? Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言 ...
- 乐观锁之版本号机制和CAS
---恢复内容开始--- 乐观锁:每次去拿数据的时候,都认为别人不会修改,不会加锁,但在更新的时候会去判断一下,此期间别人有没有更新数据,版本号机制和CAS算法就用到乐观锁,参考了https://bl ...
- Delphi WaitCommEvent函数
- 第三章·MySQL版本区别及管理
一.MySQL5.6与MySQL5.7安装的区别 1.cmake的时候加入了bostorg 2.初始化时 使用mysqld --initialize 替代mysql_install_db,其它参数没有 ...
- 最终章·MySQL从入门到高可用架构报错解决
1. 报错原因:MySQL的socket文件目录不存在. 解决方法:创建MySQL的socket文件目录 mkdir /application/mysql-5.6.38/tmp 2. 报错原因:soc ...
- NORDIC 出现NRF_ERROR_NO_MEM错误
Which SDK version are you using, is it SDK v12.x.x? Which function returns NRF_ERROR_NO_MEM? Is it s ...