hdu(预处理+线段树)
给n个数,m个询问, 问任意区间内与其它数互质的数有多少个
比如3个数1 2 4,询问[1,3] 那么答案是1
千万要记住,这样的题目,如果你不转变下,使劲往线段树想(虽然转变之后,也说要用到线段树,但是维护的东西不同了),那么会发现这样的题目,区间与区间之间是无法传递信息的,
区间与区间是无法传递信息的,区间与区间之间是无法传递信息的,重要的东西说三遍。
设n个数,存在数组a[]里面
我们预处理出,L[],和R[],L[i] 表示从i往左,第一个与a[i]不互质的数的位置+1, R[i]表示从i往右,第一个与a[i]不互质的数的位置-1
即L[i] 表示 [L[i],i]内的所有数都与a[i]互质,R[i]表示[i,R[i]]内的所有数都与a[i]互质
然后我们离线处理,将所有的询问按照左端点排序
然后枚举左端点i,将所有L[j] = i的 [j,R[j]]区间+1,因为当左端点为i时,L[j]=i的数都在各自的有效区间[j,R[j]]里面生效了
当i=询问的区间的左端点时,只要查询右端点被加了多少次就行了。
走过i时,第i个数不再生效,所以将[i,R[i]]区间-1
#include<cstdio>
#include<iostream>
#include<string.h>
#include<algorithm>
#include <vector>
using namespace std;
const int N = + ;
vector<int> prime[N];
vector<int> cL[N];
int a[N],L[N],R[N];
int mark[N];
int tree[N<<],lazy[N<<];
int ans[N];
void pushDown(int rt)
{
if(lazy[rt])
{
lazy[rt<<] += lazy[rt];
lazy[rt<<|] += lazy[rt];
tree[rt<<] += lazy[rt];
tree[rt<<|] += lazy[rt];
lazy[rt] = ;
}
}
void update(int l, int r, int rt, int L, int R, int val)
{
if(L<=l && R>=r)
{
lazy[rt]+=val;
tree[rt] += val;
return;
}
pushDown(rt);
int mid = (l+r)>>;
if(L<=mid)
update(l,mid,rt<<,L,R,val);
if(R>mid)
update(mid+,r,rt<<|,L,R,val); }
int query(int l, int r, int rt, int pos)
{
if(l==r)
{
return tree[rt];
}
pushDown(rt);
int mid = (l+r)>>;
if(pos<=mid)
return query(l,mid,rt<<,pos);
else
return query(mid+,r,rt<<|,pos);
}
struct Node
{
int l,r,id;
bool operator<(const Node&rhs)const
{
return l < rhs.l;
}
}q[N]; void getPrime()
{
for(int i=;i<=;++i)
{
if(!mark[i])
for(int j=i;j<=;j+=i)
{
mark[j] = true;
prime[j].push_back(i);//得到j的所有素数因子i
}
}
}
void init(int n)
{
memset(mark,,sizeof(mark));
for(int i=; i<prime[a[]].size(); ++i)
mark[prime[a[]][i]] = ;
L[] = ;
cL[].push_back();
for(int i=;i<=n;++i)
{
int pos = ;
for(int j=; j<prime[a[i]].size(); ++j)
{
pos = max(pos,mark[prime[a[i]][j]]);
mark[prime[a[i]][j]] = i;
}
L[i] = pos + ;
cL[L[i]].push_back(i);
}
for(int i=;i<N;++i)mark[i] = n + ;
for(int i=;i<prime[a[n]].size(); ++i)
mark[prime[a[n]][i]] = n;
R[n] = n;
for(int i=n-;i>=;--i)
{
int pos = n + ;
for(int j=;j<prime[a[i]].size(); ++j)
{
pos = min(pos,mark[prime[a[i]][j]]);
mark[prime[a[i]][j]] = i;
}
R[i] = pos - ;
}
}
int main()
{
int n,m;
getPrime();
while(scanf("%d%d",&n,&m),n+m)
{
memset(tree,,sizeof(tree));
memset(lazy,,sizeof(lazy));
for(int i=;i<=n;++i)
{
scanf("%d",&a[i]);
cL[i].clear();
}
init(n);
for(int i=;i<m;++i)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id = i;
}
sort(q,q+m);
int cur = ;
//枚举左端点
for(int i=;i<=n;++i)
{
//当左端点为i时,使得所有L[j] = i的数都在各自的区间[j,R[j]]
//所以在[j,R[j]]区间+1
for(int j=;j<cL[i].size(); ++j)
update(,n,,cL[i][j],R[cL[i][j]],);
//当询问的左端点为i时,
while(q[cur].l==i)
{
//只要询问右端点的值就行了,因为每个数都在自己能生效的区间里面+1了
ans[q[cur].id] = query(,n,,q[cur].r);
cur++;
}
//要走过第i个数了,所以第i个数不再生效了,所以将[i,R[i]]区间-1
update(,n,,i,R[i],-);
}
for(int i=;i<m;++i)
printf("%d\n",ans[i]);
}
return ;
}
hdu(预处理+线段树)的更多相关文章
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 4533 线段树(问题转化+)
威威猫系列故事——晒被子 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Tot ...
- hdu 2871 线段树(各种操作)
Memory Control Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu 4052 线段树扫描线、奇特处理
Adding New Machine Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 1542 线段树扫描(面积)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
随机推荐
- ListCtrl控件着色
最近在写一款山寨的反病毒软件,大致功能已经实现,还有一些细小的环节需要细化. 其中,在界面编程中,就用到了给ListCtrl控件着色,查看了网上一些文章,终于实现了. 其实说白了,原理很简单,就是Li ...
- 写给C语言新手的话
首先声明啊,写这个是因为一些加我QQ的朋友问我学习经验,我才写的. 另外,如果是二级党,那么请用谭浩强老师的书.然后你就可以不用看了.倒不是有偏见,而是我写的这个东西,根本不是为了考试,而是为了和新手 ...
- oracle 主键删除,联合主键的创建
1,主键的删除 ALTER TABLE TABLENAME DROP PRIMARY_KEY 运行上面的SQL能够删除主键:假设不成功能够用 ALTER TABLE TABLENAME DROP C ...
- 在phpmyadmin后台获取webshell方法汇总整理
方法一: CREATE TABLE `mysql`.`xiaoma` (`xiaoma1` TEXT NOT NULL ); INSERT INTO `mysql`.`xiaoma` (`xiaoma ...
- Android开发之style属性和提前定义样式
摘要 Android平台定义的主题样式: android:theme="@android:style/Theme.Dialog" // 将一个Activity显示为对话框模式and ...
- 设置Mysql的连接超时参数
在Mysql的默认设置中,如果一个数据库连接超过8小时没有使用(闲置8小时,即 28800s),mysql server将主动断开这条连接,后续在该连接上进行的查询操作都将失败,将 出现:e ...
- Google 搜索的基本语法
★搜索引擎的选择 先简单说一下"搜索引擎的选择". 在咱们天朝,Google 屡屡被 GFW 骚扰,导致百度占了便宜,成为份额最高的搜索引擎.不过今天这篇教程,俺还是继续拿 Goo ...
- webmagic加上了注解支持
今天有个网友在博客回帖,能不能用注解来写一个爬虫?想了想,因为Javaer总习惯结果有个对象Model(我在自己用的时候也是这样),ResultItems的key-value形式难免会有点麻烦,何不将 ...
- vijos P1352 最大获利(最小割)
请不要随便指点别人该怎么做.每一个人的人生都应该自己掌握.你给不了别人一切.你也不懂别人的忧伤. 微笑不代表快乐.哭泣不一定悲伤 不努力怎么让关心你的人幸福.不努力怎么让看不起你的人绝望. 我用生命在 ...
- ueditor编辑文章时候,复制粘贴内容,原来的图片不能显示
ueditor编辑文章时候.当现有文章有图片的时候, 再复制粘贴文本进去的时候.里面的图片就不能显示了, 编辑器查看文章Html代码,图片路径显示为:src="http://localhos ...