分析:找到每一个点的左边离他最近的不互质数,记录下标(L数组),右边一样如此(R数组),预处理

这个过程需要分解质因数O(n*sqrt(n))

然后离线,按照区间右端点排序

然后扫一遍,对于当前拍好顺序的第i个询问,将所有小于r的点加入更新

更新的过程是这样的

(1)对于刚加入点x,树状数组L[x]位置+1   把这个定义为左更新

(2)对于所有R[i]=x的点,树状数组L[i]位置-1,i位置+1   把这个定义为右更新

(3)查询是询问区间 l->r的和

时间复杂度分析,因为每个点左更新,右更新各一次,所以单组测试用例是O(nlogn)的

下面来解释为啥这样更新

查看当前询问 l , r,对于所有小于 l 的点 i,它的所有更新(左更新和右更新)不会影响到树状数组区间 l 到 r 的 和

对于在l,r区间的点 i,如果 R[i]<=r,那么对于区间 l ->r 有 1 的贡献

如果 R[i]>r,对于这个点,只有左更新L[i]+1;

如果 L[i]>=l ,对于查询区间有 1 的贡献

如果 L[i]<l,对于查询区间没有贡献

不难发现,这样对于查询区间有贡献的点,都是会和别人打架的点

所以该查询的答案就是  查询区间长度 - 树状数组区间和

然后以下看代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=2e5;
const LL mod=1e9+;
int a[N+],c[N+];
int f[N+],h[N+],k[N+];
vector<int>g[N+];
vector<int>b[N+];
struct Que
{
int l,r,id;
bool operator<(const Que &e)const
{
return r<e.r;
}
}q[N+];
int n,m;
bool vis[N+];
int prime[N+],cnt,res[N+];
void add(int x,int t)
{
for(;x<=n+;x+=(x&(-x)))
c[x]+=t;
}
int get(int x)
{
int ans=;
for(;x>;x-=(x&(-x)))
ans+=c[x];
return ans;
}
int main()
{
for(int i=; i*i<=N; ++i)
{
if(vis[i])continue;
for(int j=i*i; j<=N; j+=i)
vis[j]=;
}
for(int i=; i<=N; ++i)
if(!vis[i])prime[cnt++]=i;
for(int i=; i<=N; ++i)
{
int t=i;
for(int j=; j<cnt&&prime[j]*prime[j]<=i; ++j)
{
if(t%prime[j])continue;
g[i].push_back(prime[j]);
while(t%prime[j]==)t/=prime[j];
if(t==)break;
}
if(!vis[t]&&t!=)
g[i].push_back(t);
}
while(~scanf("%d%d",&n,&m),n)
{
memset(f,,sizeof(f));
memset(c,,sizeof(c));
for(int i=; i<=n+; ++i)
{
scanf("%d",&a[i]);
h[i]=;
k[i]=n+;
}
for(int i=; i<=n+; ++i)
{
for(int j=; j<g[a[i]].size(); ++j)
{
int x=g[a[i]][j];
h[i]=max(h[i],f[x]);
f[x]=i;
}
}
for(int i=; i<=N; ++i)
f[i]=n+;
for(int i=n+; i>; --i)
{
for(int j=; j<g[a[i]].size(); ++j)
{
int x=g[a[i]][j];
k[i]=min(k[i],f[x]);
f[x]=i;
}
}
for(int i=;i<=m;++i)
scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
sort(q+,q++m);
for(int i=;i<=n;++i)
b[i].clear();
for(int i=;i<=n+;++i)b[k[i]].push_back(i);
int x=;
for(int i=;i<=m;++i)
{
while(x<=n+&&x<=q[i].r+)
{
add(h[x],);
for(int j=;j<b[x].size();++j)
{
int y=b[x][j];
add(h[y],-);
add(y,);
}
++x;
}
int t=get(q[i].r+)-get(q[i].l);
res[q[i].id]=q[i].r-q[i].l+-t;
}
for(int i=;i<=m;++i)
printf("%d\n",res[i]); }
return ;
}

HDU 4777 Rabbit Kingdom 树状数组的更多相关文章

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

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

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

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

  3. HDU 3333 | Codeforces 703D 树状数组、离散化

    HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...

  4. HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)

    题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...

  5. HDU 3333 Turing Tree (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意就是询问区间不同数字的和. 比较经典的树状数组应用. //#pragma comment(l ...

  6. HDU 4325 Flowers(树状数组+离散化)

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...

  7. hdu 5775 Bubble Sort 树状数组

    Bubble Sort 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 Description P is a permutation of t ...

  8. HDU - 1541 Stars 【树状数组】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1541 题意 求每个等级的星星有多少个 当前这个星星的左下角 有多少个 星星 它的等级就是多少 和它同一 ...

  9. HDU 3854 Glorious Array(树状数组)

    题意:给一些结点,每个结点是黑色或白色,并有一个权值.定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大.给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前 ...

随机推荐

  1. 【BZOJ 3098】 Hash Killer II

    Description 这天天气不错,hzhwcmhf神犇给VFleaKing出了一道题:给你一个长度为N的字符串S,求有多少个不同的长度为L的子串.子串的定义是S[l].S[l + 1].... S ...

  2. 【BZOJ [1878】[SDOI2009]HH的项链

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变 ...

  3. ios App 打包

    ios 版本的 App 打包两种方式: 1. 命令行 xcodebuild exportArchive -exportFormat ipa 2. 通过 xcode Product -> Arch ...

  4. Android 二维码扫描与生成

    由于源代码比较多,本文不进行讲述,请下载源码. 源码来源于网络,请点击这里下载: http://files.cnblogs.com/wuyou/Android%E4%BA%8C%E7%BB%B4%E7 ...

  5. Source Insight的应用技巧、宏功能

    目录 1 简介... 5 2 搭建我们的SI环境... 5 2.1 搭建步骤... 5 2.2 说明... 6 3 应用技巧... 6 3.1 初级应用技巧... 6 3.1.1 解决字体不等宽与对齐 ...

  6. 影响pogo pin连接器使用寿命的因素

    精细化.安装简易化及使用寿命长是现在数码电子产品的趋势发展,pogo pin连接器体积小而且弹簧伸缩式设计,可以更好的缩小数码电子产品的尺寸并且连接安装更加的简单方便,因此pogo pin连接器得到了 ...

  7. 编译qt-mobility

    因为用到了qt-mobility,必须自己编译一下,参考列出了参考资料. 参考: 1. windows下编译qt-mobility  http://hi.baidu.com/xchinux/blog/ ...

  8. AC题目简解-dp

    dp类:A - Bridging signals ZOJ 3627 POJ1631 HDU1950给出一个从1-n的数字排列,求最长上升子序列长度.直接说解法吧.新开一个数组d,d[i]表示的是能构成 ...

  9. jquery的smartWizard插件使用方法

    jquery 的smartWizard插件常用在一些向导式的,按步骤的功能中,是的用户按照我们设定的步骤进行操作,这样一方面有较好的用户体验,可以将庞大的表格 数据分解成多个步骤,是的每个步骤的数据量 ...

  10. java文档注释主要使用方法

    一.java包含哪些注释 1.//用于单行注释. 2./*...*/用于多行注释,从/*开始,到*/结束,不能嵌套. 3./**...*/则是为支持jdk工具javadoc.exe而特有的注释语句.这 ...