题目大意:给一个n个整数的数列,q次询问,每次询问区间[l,r]中与区间中其它数互质的数的个数.。

题目分析:离线处理,这里以询问区间的左端点从小到大的顺序为例。为了叙述方便,用f(l,r)表示区间[l,r]中与区间中其它数互质的数的个数.。每次用线段树或树状数组维护以 a(i)(1<=i<=n) 为左端点的所有区间的 f 值的前缀和。左端点从1~n,每变化一次,便做一次更新操作。这样,f(l,r)=sum(l)-sum(r+1)。对于数列中的每个元素a(i),预处理出其左边第一个不与他互质的数li(i),同样预处理出ri(i)。当左端点由a(i)变为a(i+1)时,要将区间[i+1,ri(i)-1]的 f 值都减1,同理,如果存在j>i并且li(j)=i,那么就要将区间[i+1,ri(j)-1]的 f 值都加1。

代码如下(用树状数组维护):

# include<iostream>
# include<cstdio>
# include<map>
# include<set>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std; const int N=200000; struct Node
{
int id,l,r;
};
Node nde[N+1];
int a[N+1];
int li[N+1];
int ri[N+1];
int mark[N+1];
int ans[N+1];
int sum[N+1];
vector<int>edge[N+1];
vector<int>v[N+1];
int n; bool comp(const Node &a,const Node &b)
{
return a.l<b.l;
} void init()
{
for(int i=2;i<=N;++i)
for(int j=i;j<=N;j+=i)
v[j].push_back(i);
} int lowbit(int x)
{
return x&(-x);
} void add(int x,int val)
{
while(x>=1){
sum[x]+=val;
x-=lowbit(x);
}
} int getSum(int x)
{
int res=0;
while(x<=n){
res+=sum[x];
x+=lowbit(x);
}
return res;
} int main()
{
init();
int m;
while(scanf("%d%d",&n,&m)&&(n+m))
{
for(int i=1;i<=n;++i){
scanf("%d",a+i);
edge[i].clear();
}
memset(mark,0,sizeof(mark));
for(int i=1;i<=n;++i){
li[i]=0;
for(int j=0;j<v[a[i]].size();++j){
li[i]=max(li[i],mark[v[a[i]][j]]);
mark[v[a[i]][j]]=i;
}
}
memset(mark,1,sizeof(mark));
for(int i=n;i>=1;--i){
ri[i]=n+1;
for(int j=0;j<v[a[i]].size();++j){
ri[i]=min(ri[i],mark[v[a[i]][j]]);
mark[v[a[i]][j]]=i;
}
} memset(sum,0,sizeof(sum));
for(int i=1;i<=n;++i){
if(li[i]){
edge[li[i]].push_back(i);
}else{
add(i,1);
if(ri[i]<=n) add(ri[i],-1);
}
}
for(int i=1;i<=m;++i){
scanf("%d%d",&nde[i].l,&nde[i].r);
nde[i].id=i;
} int id=1;
sort(nde+1,nde+m+1,comp); for(int i=1;i<=n&&id<=m;++i){
while(nde[id].l==i){
ans[nde[id].id]=(getSum(nde[id].l)-getSum(nde[id].r+1));
++id;
}
add(i,-1);
if(ri[i]<=n) add(ri[i],1);
for(int j=0;j<edge[i].size();++j){
int x=edge[i][j];
add(x,1);
if(ri[x]<=n) add(ri[x],-1);
}
}
for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
}
return 0;
}

  

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 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

  4. HDU 4777 Rabbit Kingdom 树状数组

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

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

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

  6. HDU 4777 Rabbit Kingdom

    素因子分解,树状数组.$ACM/ICPC$ $2013$杭州区域赛$H$题. 首先需要处理出数字$a[i]$左边最远到$L[i]$,右边最远到$R[i]$区间内所有数字都与$a[i]$互质. 那么对于 ...

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

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

  8. hdu 1698 线段树 区间更新 区间求和

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)

    伸展数最基本操作的模板,区间求和,区间更新.为了方便理解,特定附上一自己搞的搓图 这是样例中的数据输入后建成的树,其中的1,2是加入的边界顶点,数字代表节点编号,我们如果要对一段区间[l, r]进行操 ...

  10. HDU(1698),线段树区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 区间更新重点在于懒惰标记. 当你更新的区间就是整个区间的时候,直接sum[rt] = c*(r- ...

随机推荐

  1. 分享Windows Server 2012 R2的获取正版密钥方法

    然后使用“我有ISIC卡”验证,目前可用号码:S420546009858. 分享Windows Server 2012 R2的获取正版密钥方法. 首先登陆dreamspark注册一个账号https:/ ...

  2. winform错误提示 :窗口类名无效(Window class name is not valid)

    winfrom 程序在 xp 操作系统上报错提示 窗口类名无效(Window class name is not valid) 解决方法 注释 Program类 里 这句 Application.En ...

  3. 一个完整的ansible实施目录示例

    当前目录:

  4. 主线程中一定不能放耗时操作,必须要开子线程,比如下载文件,不然会不让你拿到输入流--报错显示android.os.NetworkOnMainThreadException

    1.必须要开子线程来操作耗时操作,android.os.NetworkOnMainThreadException new Thread(new Runnable() { @Override publi ...

  5. Tarjan算法求有向图的强连通分量

    算法描述 tarjan算法思想:从一个点开始,进行深度优先遍历,同时记录到达该点的时间(dfn记录到达i点的时间),和该点能直接或间接到达的点中的最早的时间(low[i]记录这个值,其中low的初始值 ...

  6. Node.js +Express+MongoDB+mogoose+ejs+bootstrap+jquery

    Node.js + MongoDB 项目实战(二)  创建项目 在项目实战(一)中,已经配置好了开发环境(详见:http://www.cnblogs.com/jameslong/articles/34 ...

  7. 第一个PHP程序

    <html> <head> <title><?php echo"这是第一个php程序"?></title> <st ...

  8. 【转】利用 Bootstrap 进行快速 Web 开发

    原文转自:http://blog.jobbole.com/53961/ 了解如何使用 Bootstrap 快速开发网站和 Web 应用程序(包括移动友好型应用程序).Bootstrap 以 LESS ...

  9. C,C++宏中#与##的讲解[转]

    MoreWindows 专注于Windows编程 C,C++宏中#与##的讲解 文中__FILE__与示例1可以参见<使用ANSI C and Microsoft C++中常用的预定义宏> ...

  10. js取配置文件内容

    使用 jQuery.i18n.properties 实现 Web 前端的国际化 http://www.ibm.com/developerworks/cn/web/1305_hezj_jqueryi18 ...