Codeforces G. Ant colony

题目描述:

F. Ant colony
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Mole is hungry again. He found one ant colony, consisting of n ants, ordered in a row. Each ant i (1 ≤ i ≤ n) has a strength si.

In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He chooses two numbers l and r(1 ≤ l ≤ r ≤ n) and each pair of ants with indices between l and r (inclusively) will fight. When two ants i and j fight, ant i gets one battle point only if si divides sj (also, ant j gets one battle point only if sj divides si).

After all fights have been finished, Mole makes the ranking. An ant i, with vi battle points obtained, is going to be freed only if vi = r - l, or in other words only if it took a point in every fight it participated. After that, Mole eats the rest of the ants. Note that there can be many ants freed or even none.

In order to choose the best sequence, Mole gives you t segments [li, ri] and asks for each of them how many ants is he going to eat if those ants fight.
Input

The first line contains one integer n (1 ≤ n ≤ 105), the size of the ant colony.

The second line contains n integers s1, s2, ..., sn (1 ≤ si ≤ 109), the strengths of the ants.

The third line contains one integer t (1 ≤ t ≤ 105), the number of test cases.

Each of the next t lines contains two integers li and ri (1 ≤ li ≤ ri ≤ n), describing one query.
Output

Print to the standard output t lines. The i-th line contains number of ants that Mole eats from the segment [li, ri].
Sample test(s)
input

5
1 3 2 4 2
4
1 5
2 5
3 5
4 5

output

4
4
1
1

Note

In the first test battle points for each ant are v = [4, 0, 2, 0, 2], so ant number 1 is freed. Mole eats the ants 2, 3, 4, 5.

In the second test case battle points are v = [0, 2, 0, 2], so no ant is freed and all of them are eaten by Mole.

In the third test case battle points are v = [2, 0, 2], so ants number 3 and 5 are freed. Mole eats only the ant 4.

In the fourth test case battle points are v = [0, 1], so ant number 5 is freed. Mole eats the ant 4.

思路:

题目的意思是说,给一个数列,看里面有多少个数,这样的数可以被数列中的其他所有数整除。显然这个数就是数列的gcd啦!为什么呢?首先gcd可以满足条件,然后如果不是gcd,那就是gcd的因数,可是数列中的数如果有一个是gcd的因数那它小于等于gcd,而它又不可能比gcd小,只能相等。(为什么,它要是比gcd小,那它才会是gcd)。我怎么会有这么奇怪的想法怀疑它不是gcd (?`?Д?´)!!

又因为是区间查询问题,整一个线段树来维护区间gcd,和等于gcd的数目。注意的是build函数里这么pushup,还有查询函数怎么统计结果。

pushup就是对一个节点求左右两个节点的gcd,如果左边的节点的gcd与这个gcd相等,统计数目加左边的相等数目,如果右边的等就再加右边的数目,不等就是零。

query函数求答案的时候要看一下当前区间答案来自哪里,是左区间,还是右区间,还是两边都有?分别处理一下就好。

这道题竟然连懒标记都没用,就是静态查询√

代码:

  1 #include <iostream>
  2 #define max_n 100005
  3 using namespace std;
  4 int n;
  5 int t;
  6 struct node
  7 {
  8     int num;
  9     int gcd;
 10     int id;
 11 }tree[max_n<<2];
 12 int a[max_n];
 13
 14 int GCD(int a,int b)
 15 {
 16     if(a<b) swap(a,b);
 17     int r = a%b;
 18     if(r==0)
 19     {
 20         return b;
 21     }
 22     return GCD(b,r);
 23 }
 24 void build(int id,int l,int r)
 25 {
 26     if(l==r)
 27     {
 28         tree[id].gcd = a[l];
 29         tree[id].num = 1;
 30         return;
 31     }
 32     int mid = (l+r)>>1;
 33     build(id<<1,l,mid);
 34     build(id<<1|1,mid+1,r);
 35     int gcd = GCD(tree[id<<1].gcd,tree[id<<1|1].gcd);
 36     tree[id].num = 0;
 37     tree[id].gcd = gcd;
 38     if(tree[id<<1].gcd==gcd)
 39     {
 40         tree[id].num += tree[id<<1].num;
 41     }
 42     if(tree[id<<1|1].gcd==gcd)
 43     {
 44         tree[id].num += tree[id<<1|1].num;
 45     }
 46 }
 47 pair<int,int> query(int id,int L,int R,int l,int r)
 48 {
 49     //cout << "l " << l << " r " << r << endl;
 50     if(L<=l&&r<=R)
 51     {
 52         int gcd = tree[id].gcd;
 53         int num = tree[id].num;
 54         //cout << "gcd " << gcd << "num " << num << endl;
 55         return pair<int,int>(gcd,num);
 56     }
 57     int mid = (l+r)>>1;
 58     int ans = 0;
 59     pair<int,int> res1,res2;
 60     if(L<=mid){ res1 = query(id<<1,L,R,l,mid); }
 61     if(mid<R) {res2 = query(id<<1|1,L,R,mid+1,r);}
 62     int gcd;
 63     if(L<=mid)
 64     {
 65         if(mid<R)
 66         {
 67             gcd = GCD(res1.first,res2.first);
 68             //cout << "gcd " << gcd << endl;
 69             if(res1.first==gcd)
 70                 ans+=res1.second;
 71             if(res2.first==gcd)
 72                 ans+=res2.second;
 73         }
 74         else
 75         {
 76             gcd = res1.first;
 77             ans += res1.second;
 78         }
 79     }
 80     else
 81     {
 82         gcd = res2.first;
 83         ans += res2.second;
 84     }
 85     //cout << "gcd " << gcd << " ans " << ans << endl;
 86     return pair<int,int>(gcd,ans);
 87 }
 88 int main()
 89 {
 90     //cout << GCD(1,3) << endl;
 91     cin >> n;
 92     for(int i = 1;i<=n;i++)
 93     {
 94         cin >> a[i];
 95     }
 96     build(1,1,n);
 97     cin >> t;
 98     for(int q = 0;q<t;q++)
 99     {
100         int L,R;
101         cin >> L >> R;
102         cout << R-L+1-query(1,L,R,1,n).second << endl;;
103     }
104     return 0;
105 }

原文地址:https://www.cnblogs.com/zhanhonhao/p/11256670.html

时间: 2024-10-11 22:50:43

Codeforces G. Ant colony的相关文章

Codeforces 474F - Ant colony

注意到每个区间生存下来的蚂蚁的长度等于区间的gcd 于是可以先预处理出区间的gcd 然后二分查找就好了 预处理gcd我这里用的是倍增法 总的时间复杂度O(NlogN) /* Cf 271F 倍增求区间GCD 对下标二分 时间复杂度O(NlogN) */ #include <iostream> #include <algorithm> #include <vector> #include <map> using namespace std; const int

Codeforces Round #271 (Div. 2) F.Ant colony(线段树 + 统计区间内某数的个数)

F. Ant colony Mole is hungry again. He found one ant colony, consisting of n ants, ordered in a row. Each ant i (1 ≤ i ≤ n) has a strength si. In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He c

Codeforces 29D Ant on the Tree 树的遍历 dfs序

题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径,要求遍历叶子节点时按照给定叶子节点的先后顺序访问. 思路: 给每个节点加一个优先级. 把最后一个叶子节点到父节点的路径上的点优先级改为1 把倒数第二个叶子节点到父节点的路径上的点优先级改为2 如此每个点就有一个优先级,每个访问儿子节点时先访问优先级大的即可 对于无解的判断:得到的欧拉序列不满足输入的叶子节点顺序即是无解. #include <cstdio> #

CodeForces 29D Ant on the Tree

给一颗树,1为根,要求遍历树上所有点,给出叶子结点的访问顺序,限制每条边至多访问两次. 首先这是一棵树,那么两点之间的路线是确定的,所以我第一遍dfs预处理出从根节点到每个叶子的路径保存,以便后面输出. 那么就按照题目要求输出叶子结点的顺序依次输出,然后从一个叶子到下一个叶子的时候,从他们的最近公共祖先转折,所以我还预处理了相邻两个叶子结点的LCA. #include <iostream> #include <cstdlib> #include <cstring> #i

ant colony algorithm &amp;&amp; decision tree

// AntColony.cpp : 定义控制台应用程序的入口点. // //#include "stdafx.h" #include<iostream> #include<math.h> #include<time.h> #include <fstream> #include <string> #include <iostream> #include <vector> using namespace

Codeforces G. Ciel the Commander

题目描述: Ciel the Commander time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Now Fox Ciel becomes a commander of Tree Land. Tree Land, like its name said, has n cities connected by n?-?1 undire

Jenknis+Ant+SVN+Tomact 持续构建

我们公司现在的开发环境是这样的,在本地开发完一个新的功能,测试无误直接上传到SVN:接下来就是将这次开发的功能从界面到后面理一遍,理清晰了就开始一点点的复制到服务器上的IDE中编译和发布. 上面的情况已经很繁琐了,下面这种情况会更糟糕.上线的系统,后期维护中会对很多功能进行完善,系统也会有周期性的测试.我们公司就是这样的,公司每个组都有测试人员,同时会请第三方公司测试.问题来了,在哪里做测试呢?每次都需要临时搭建一个测试环境,供测试人员测试. 步骤: a.测试人员将提出的bug交给开发人员 b.

Ant + ivy的安装

想要使用ivy 必须先安装ant和JDK,然后才可以安装ivy哦!不过安装过程很简单. 1.Jdk安装 JDK的安装大家都应该知道,安装之后再配置环境变量就ok了!配置如下所示: JAVA_HOME:    C:\Program Files\Java\jdk1.5.0_16 Path:                %JAVA_HOM%\bin;%JAVA_HOME%\jre\bin; CLASS_PATH:  .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\t

(WAWAWAWAWAWAW) G. Periodic RMQ Problem

没有联通门 : Codeforces G. Periodic RMQ Problem /* Codeforces G. Periodic RMQ Problem MMP 什么动态开点线段树啊 ... YY了个非常可行的做法 码完后交一下发现RE了几个点.. 就思考哪里有问题 突然之间, 老泪纵横.. MMP 我写了这是个什么玩意啊 仔细想想我TM不就是写了个全空间的主席树吗....脑子有病啊.. 静言思之, 躬自悼矣..反是不思,亦已焉哉 不写啦! */ #include <cmath> #i