素因子分解,树状数组。$ACM/ICPC$ $2013$杭州区域赛$H$题。

首先需要处理出数字$a[i]$左边最远到$L[i]$,右边最远到$R[i]$区间内所有数字都与$a[i]$互质。

那么对于左端点在$[L[i],i]$并且右端点在$[i,R[i]]$的询问,$a[i]$就可以作出一个贡献。

接下来的问题就可以转化为二维平面上有很多矩形,每次询问一个点被多少矩形覆盖。可以离线操作,类似于扫描线的思想做就可以了。

素因子分解需要一开始把$20$万个数字都处理好,避免每组测试数据内重复处理。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream> #include<queue>
using namespace std; const int maxn=2e5+;
int w[maxn],n,q;
struct X
{
int x,y,ans,id;
} s[maxn]; struct OP
{
int x,y1,y2;
} add[maxn],del[maxn]; bool com[maxn];
int primes, prime[maxn],L[maxn],R[maxn];
int pre[maxn];
int c[maxn],hh; vector<int>Prime[maxn]; int lowbit(int x) { return x&(-x); }
void ADD(int p, int val) { while (p <= n) c[p] = c[p] + val, p = p + lowbit(p); }
int sum(int p) { int r = ; while (p > ) r = r + c[p], p = p - lowbit(p); return r; }
void update(int L, int R, int val) { ADD(L, val); ADD(R + , -val); } void solve()
{
primes = ;
memset(com,false,sizeof(com));
com[] = com[] = true;
for (int i = ; i < maxn; ++i)
{
if (!com[i])
{
prime[++primes] = i;
}
for (int j = ; j <= primes && i*prime[j] < maxn; ++j)
{
com[i*prime[j]] = true;
if (!(i % prime[j]))
break;
}
} for(int i=;i<=;i++)
{
int tp = i;
for(int j=;j<=primes&&tp!=;j++)
{
if(tp%prime[j]) continue; Prime[i].push_back(prime[j]); while(!(tp%prime[j])) tp /= prime[j]; if(!com[tp]&&tp>)
{
Prime[i].push_back(tp);
break;
}
}
}
} bool cmp1(X a,X b) { return a.x<b.x; }
bool cmp2(OP a,OP b) { return a.x<b.x; }
bool cmp3(X a,X b) { return a.id<b.id; } int main()
{
solve(); while(~scanf("%d%d",&n,&q))
{
if(n==&&q==) break;
for(int i=; i<=n; i++) scanf("%d",&w[i]); for(int i=; i<=q; i++) scanf("%d%d",&s[i].x,&s[i].y), s[i].id=i;
sort(s+,s++q,cmp1); for(int i=;i<=;i++) pre[i]=;
for(int i=;i<=n;i++)
{
if(w[i]==) L[i]=;
else
{
L[i]=;
for(int j=;j<Prime[w[i]].size();j++)
{
L[i]=max(L[i],pre[Prime[w[i]][j]]+);
pre[Prime[w[i]][j]]=i;
}
}
} for(int i=;i<=;i++) pre[i]=n+;
for(int i=n;i>=;i--)
{
if(w[i]==) R[i]=n;
else
{
R[i]=n+;
for(int j=;j<Prime[w[i]].size();j++)
{
R[i]=min(R[i],pre[Prime[w[i]][j]]-);
pre[Prime[w[i]][j]]=i;
}
}
} int sz1=,sz2=;
for(int i=;i<=n;i++)
{
add[sz1].x=L[i]; add[sz1].y1=i; add[sz1].y2=R[i]; sz1++;
del[sz2].x=i; del[sz2].y1=i; del[sz2].y2=R[i]; sz2++;
} sort(add,add+sz1,cmp2);
sort(del,del+sz2,cmp2); int idq=,idadd=,iddel=; memset(c,,sizeof c); for(int i=;i<=n;i++)
{
while(idadd<sz1&&add[idadd].x==i)
{
update(add[idadd].y1,add[idadd].y2,);
idadd++;
}
while(idq<=q&&s[idq].x==i)
{
s[idq].ans=sum(s[idq].y);
idq++;
}
while(iddel<sz2&&del[iddel].x==i)
{
update(del[iddel].y1,del[iddel].y2,-);
iddel++;
}
} sort(s+,s++q,cmp3); for(int i=;i<=q;i++) printf("%d\n",s[i].ans); }
return ;
}

HDU 4777 Rabbit Kingdom的更多相关文章

  1. HDU 4777 Rabbit Kingdom(树状数组)

    HDU 4777 Rabbit Kingdom 题目链接 题意:给定一些序列.每次询问一个区间,求出这个区间和其它数字都互质的数的个数 #include <cstdio> #include ...

  2. HDU 4777 Rabbit Kingdom (2013杭州赛区1008题,预处理,树状数组)

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. HDU 4777 Rabbit Kingdom --容斥原理+树状数组

    题意: 给一个数的序列,询问一些区间,问区间内与区间其他所有的数都互质的数有多少个. 解法: 直接搞有点难, 所谓正难则反,我们求区间内与其他随便某个数不互质的数有多少个,然后区间长度减去它就是答案了 ...

  4. HDU 4777 Rabbit Kingdom 树状数组

    分析:找到每一个点的左边离他最近的不互质数,记录下标(L数组),右边一样如此(R数组),预处理 这个过程需要分解质因数O(n*sqrt(n)) 然后离线,按照区间右端点排序 然后扫一遍,对于当前拍好顺 ...

  5. hdu 4778 Rabbit Kingdom(减少国家)

    题目链接:hdu 4778 Rabbit Kingdom 题目大意:Alice和Bob玩游戏,有一个炉子.能够将S个同样颜色的宝石换成一个魔法石.如今有B个包,每一个包里有若干个宝石,给出宝石的颜色. ...

  6. hdu 4777 树状数组+合数分解

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  7. P - 区间与其他数互质数的个数 HDU - 4777

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分法)

    Rabbit's String Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  9. HDU 5030 Rabbit's String

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5030 题意:给出一个长度为n的串S,将S分成最多K个子串S1,S2,……Sk(k<=K).选出每 ...

随机推荐

  1. [译]Java 设计模式之备忘录

    (文章翻译来自Java Design Pattern: Memento) memento是一个保存另外一个对象内部状态拷贝的对象.这样以后就可以将该对象恢复到原先保存的状态. 在将来时空旅行将成为显示 ...

  2. 在openwrt上编译最简单的一个ipk包文件

    1 什么是opkg Opkg 是一个轻量快速的套件管理系统,目前已成为 Opensource 界嵌入式系统标准.常用于路由.交换机等嵌入式设备中,用来管理软件包的安装升级与下载. opkg updat ...

  3. OpenCV2第一个马拉松8环——画一个柱状图

    在包里 灰度直方图 彩色直方图 葵花宝典 直方图的理论还是非常丰富的,应用也非常多,诸如: 直方图均衡化 直方图匹配(meanshift,camshift) 在这里,我先介绍基础.怎样绘制图像的直方图 ...

  4. {{angular.js 使用技巧}} - 实现计算列属性

    前端MV*框架现在有很多,其中某些框架有计算列(又叫监控属性),比如:微软推荐的 Knockout.js 和博客园司徒正美的 avalon.js 框架. 本人只使用过 Knockout.js,aval ...

  5. Coffee

    Coffee 从接触Spring 到现在已经差不多2年多了,期间用它做过几个项目,从个人使用角度来说,Spring无疑是非常的成熟和方便的,但是知道怎么用,却不知道原理是码农和攻城师的区别,现在准备自 ...

  6. Json.Net6.0

    Json.Net6.0入门学习试水篇   前言 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中表 ...

  7. c++类的构造函数与析构函数

    为什么用构造函数与析构函数 构造函数: c++目标是让使用类对象就像使用标准类型一样,但是常规化的初始化句法不适用与类类型. ; //基本类型 struct thing { char *pn; int ...

  8. c++ virtual function 虚函数面试题

    下面的代码输出什么? #include<iostream> using namespace std; class A { public: virtual void foo() { cout ...

  9. General Structure of Quartz.NET and How To Implement It

    General Structure of Quartz.NET and How To Implement It   General Structure of Quartz.NET and How To ...

  10. generating permunation

    generating permunation——全排列(算法汇总) #include <iostream> #include <string> #include <vec ...