Rabbit Kingdom

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3360    Accepted Submission(s): 1135

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=4777

Problem Description

  Long
long ago, there was an ancient rabbit kingdom in the forest. Every
rabbit in this kingdom was not cute but totally pugnacious, so the
kingdom was in chaos in season and out of season.
  n rabbits were
numbered form 1 to n. All rabbits' weight is an integer. For some
unknown reason, two rabbits would fight each other if and only if their
weight is NOT co-prime.
  Now the king had arranged the n rabbits in a
line ordered by their numbers. The king planned to send some rabbits
into prison. He wanted to know that, if he sent all rabbits between the
i-th one and the j-th one(including the i-th one and the j-th one) into
prison, how many rabbits in the prison would not fight with others.
  Please note that a rabbit would not fight with himself.
 

Input

  The input consists of several test cases.
  The first line of each test case contains two integer n, m, indicating the number of rabbits and the queries.
  The following line contains n integers, and the i-th integer Wi indicates the weight of the i-th rabbit.
  Then
m lines follow. Each line represents a query. It contains two integers L
and R, meaning the king wanted to ask about the situation that if he
sent all rabbits from the L-th one to the R-th one into prison.
  (1 <= n, m, Wi <= 200000, 1 <= L <= R <= n)
  The input ends with n = 0 and m = 0.
 

Output

  For every query, output one line indicating the answer.
 

Sample Input

3 2
2 1 4
1 2
1 3
6 4
3 6 1 2 5 3
1 3
4 6
4 4
2 6
0 0

Sample Output

2
1
1
3
1
2

Hint

  In the second case, the answer of the 4-th query is 2, because only 1 and 5 is co-prime with other numbers in the interval [2,6] .

 

Source

 

题意

给你一个区间,然后求每个区间内与其他数都互质的数有多少个。
 

题解

树链剖分专题中乱入一道树状数组的题目,然后就开始想啊想啊,最终放弃思考,瞥了一眼题解,想起了HH的项链,然后觉得相似,就做啊做啊,最后发现有不可弥补的漏洞,继续看题解,原来和我想法差那么远呀。
 
不知道大家有没有遇见过这样一道题;一个序列,每个位置i都有一个依赖位置Y[i],且i和Y[i]互相依赖(即i依赖Y[i],则Y[i]依赖i),现给你任意多个区间(l,r),求有多少点依赖点也在这个区间里。
如果没做过没关系,因为我接下来会将两题连续细细道来。
可以先不看橙字部分。。。

 

开始正经讲题解啦 :
  第一步也是关键的一步,想不到就没办法:就是求每个位置i,前面第一个与它不互质的数的位置L[i],以及后面第一个不互质数的位置R[i]。至于这个怎么求,等下再讲。
  有了这个数组之后,问题转化为求一个区间(l,r)内L[i]和R[i]都不在这个区间的数有多少个。
  如果这么想,每个位置i会有两个影响值,就不好做了,那么我们反过来求有多少i是不合法的。 不合法的个数=L[i]>=l的个数+R[i]<=r的个数-l<=L[i]&&R[i]<=r的个数。
  然后我们将所有询问区间按照右端点从小到大排序,保证扫描时右端点ll递增。
 
为了不那么抽象,我还是先讲做法再讲原理吧:
  一开始ll设为0,表示没有一个位置被更新。 每个询问区间我们定义为(li,ri)
 
  1.依次枚举询问区间把未更新的区间(即ll+1 ~ ri) 依次更新,对于每个位置j(ll+1<=j<=ri),来说这样枚举的一个非常重要的性质:剩下的询问区间r[i]>=j(即如果这个区间包含l[j]那么一定包含j)
  2.这样我们是不是把l[j]加上1即可(我称这种模型为点对贡献模型,也就是橙色字体的那题)当然要是r[j]<=ri,l[j]就没有用了,这时我们对于j,枚举所有r[x]==j的点,令x位置+1,l[x]位置-1,(即区间包含x,一定包含r[x],且包含l[x]也不会对x有影响)
  3.统计答案直接求sum(li,ri),即li到ri的和。
 
这样题目就算做完了,这种题目第一次做感觉很晕,建议研究一下:
1.为什要保证右端点单增
2.怎样统计点对答案
3.可不可以换成左端点单增
 
还有最后一个东西,那就算怎么求l[i]和r[i]呢?我们可以求出每个数的质因子,然后用一个last数组存每个质因子上一次在哪里出现,对于每个点i,枚举所有它的质因子zj,l[i]=max(l[i],last[zj]),r[i]同理。
 

代码:

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200050
const int maxn=;
int n,m,P_num;
int prime[N],f[N],last[N],ans[N],c[N];
int L[N],R[N];
vector<int> V[N];
struct Query
{
int l,r,id;
bool operator <(const Query&b)const
{return r<b.r;}
}que[N];
template<typename T>void read(T&x)
{
ll k=; char c=getchar();
x=;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit();
while(isdigit(c))x=x*+c-'',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void update(int x,int tt){while(x<=maxn){c[x]+=tt;x+=x&-x;}}
int query(int x){int ans=;while(x){ans+=c[x];x-=x&-x;}return ans;}
void init()
{
for(int i=;i<=maxn;i++)
{
if (f[i]==)
{
prime[++P_num]=i;
int k=i;
while(k+i<=maxn)f[k+i]=,k+=i;
}
}
}
void add(int i,int zs)
{
R[last[zs]]=min(R[last[zs]],i);
L[i]=max(L[i],last[zs]);
last[zs]=i;
}
void work()
{
read(n); read(m);
if (n==)exit();
for(int i=;i<=n;i++)
{
int x;
L[i]=; R[i]=n+;
read(x);
for(int j=;j<=P_num&&x>&&f[x]==;j++)
if (x%prime[j]==)
{
add(i,prime[j]);
while(x%prime[j]==)x/=prime[j];
}
if (x>)add(i,x);
}
for(int i=;i<=n;i++) V[R[i]].push_back(i);
for(int i=;i<=m;i++)
{
read(que[i].l); read(que[i].r);
que[i].id=i;
}
sort(que+,que+m+);
int r=;
for(int i=;i<=m;i++)
{
for(int j=r+;j<=que[i].r;j++)
{
if (L[j])update(L[j],);
for(int k=;k<V[j].size();k++)
{
if (L[V[j][k]])update(L[V[j][k]],-);
update(V[j][k],);
}
}
r=que[i].r;
ans[que[i].id]=que[i].r-que[i].l+;
ans[que[i].id]-=query(que[i].r)-query(que[i].l-);
}
for(int i=;i<=m;i++)printf("%d\n",ans[i]);
}
void clear()
{
for(int i=;i<=maxn;i++)V[i].clear();
memset(last,,sizeof(last));
memset(c,,sizeof(c));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
init();
while()
{
clear();
work();
}
}
 

P - 区间与其他数互质数的个数 HDU - 4777的更多相关文章

  1. 区间求小于等于k的数字个数 hdu4177

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题目意思给出一个序列,叫我们求一个区间里面小于等于k的数字个数. 这里面我用分块和主席树两种方法 ...

  2. hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙

    /** 题目:hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4106 ...

  3. AC日记——数1的个数 openjudge 1.5 40

    40:数1的个数 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个十进制正整数n,写下从1到n的所有整数,然后数一下其中出现的数字“1”的个数. 例如当n=2时,写下1,2. ...

  4. 数对的个数(cogs610)

    Description出题是一件痛苦的事情!题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的A+B Problem,改用A-B了哈哈! 好吧,题目是这样的:给出一串数以及一个数字C,要求计算出所有A- ...

  5. sum_series() 求一列数的指定个数的数和(5个数字的和)

    #include <stdio.h> #include <stdarg.h> /*用sum_series() 求一列数的指定个数的数和(5个数字的和)*/ double sum ...

  6. SELECT INTO和INSERT INTO SELECT的区别 类似aaa?a=1&b=2&c=3&d=4,如何将问号以后的数据变为键值对 C# 获取一定区间的随即数 0、1两个值除随机数以外的取值方法(0、1两个值被取值的概率相等) C# MD5 加密,解密 C#中DataTable删除多条数据

    SELECT INTO和INSERT INTO SELECT的区别   数据库中的数据复制备份 SELECT INTO: 形式: SELECT value1,value2,value3 INTO Ta ...

  7. hdu 5062 单峰数(12321)的个数

    http://acm.hdu.edu.cn/showproblem.php?pid=5062 模拟筛出对称单峰数(12321)的个数,水题 #include <cstdio> #inclu ...

  8. POJ3180(有向图强连通分量结点数>=2的个数)

    The Cow Prom Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1451   Accepted: 922 Descr ...

  9. cogs 610. 数对的个数

    610. 数对的个数 ★★   输入文件:dec.in   输出文件:dec.out   简单对比时间限制:1 s   内存限制:128 MB Description出题是一件痛苦的事情!题目看多了也 ...

随机推荐

  1. AngularJS:教程

    ylbtech-AngularJS:教程 1.返回顶部 1. AngularJS 教程 AngularJS 通过新的属性和表达式扩展了 HTML. AngularJS 可以构建一个单一页面应用程序(S ...

  2. zabbix监控MySQL部署实战

    1.部署zabbix监控. 1.1 建用户组和用户 groupadd zabbix useradd -d /home/zabbix -g zabbix -m zabbix passwd zabbix ...

  3. 微信小程序中遇到的wx:if问题

    最近在项目中遇到wx:if问题进行梳理一下,有个需求就是有数据的时候显示数据列表,没有数据的时候就显示‘去赚钱’的页面,这可以放在一个页面进行显示,就要用到wx:if判断.我在js中设置了一个变量sh ...

  4. java之多态性

    多态性(Polymorphism):一个东西,在不同的情况下,呈现出不同的行为两类:静态多态性:函数重载void add(int a,int b){}void add(int a,int b,int ...

  5. angularJS学习(三)——搭建学习环境

    1.安装Node.js 和Testacular 1.1. 安装Node.js及配置部分,在另一篇博文:node.js的安装里面讲到了,地址是:http://www.cnblogs.com/tianxu ...

  6. 201671010140. 2016-2017-2 《Java程序设计》java学习第六章

    java学习第六章    本周对与java中的接口,lambda表达式与内部类进行了学习,以下是我在学习中的一些体会:    1.接口: <1>.接口中的所有常量必须是public sta ...

  7. SpringMVC总结四:拦截器简单介绍

    首先要说一下HandlerExecutionChain: HandlerExecutionChain是一个执行链,当用户的请求到达DispatcherServlet的时候,DispatcherServ ...

  8. mfs教程(三)

    mfs文件系统(三) 使用  MooseFS 一.挂载文件系统 启动管理服务器(master server)和数据服务器(chunkservers) (chunkservers一个是必需的,但至少两个 ...

  9. 使用FileReader与FileWriter读写数据

    -------------siwuxie095                         工程名:TestFileRW 包名:com.siwuxie095.filerw 类名:FileReade ...

  10. 2014蓝桥杯B组初赛试题《奇怪的分式》

    题目描述: 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是:     1/4 乘以 8/5      小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png)   ...