CF474F Ant colony
2024-08-31 13:29:14
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=;
int a[N],n,m,tmp;
struct tree{
int l,r,gcd,sum;
}tr[N*];
int gcd(int x,int y){
if(y==)return x;
else return gcd(y,x%y);
}
void update(int now){
int GCD=gcd(tr[now*].gcd,tr[now*+].gcd);
tr[now].gcd=GCD;
if(tr[now*].gcd==tr[now*+].gcd)tr[now].sum=tr[now*].sum+tr[now*+].sum;
else if(tr[now*].gcd==GCD)tr[now].sum=tr[now*].sum;
else if(tr[now*+].gcd==GCD)tr[now].sum=tr[now*+].sum;
else tr[now].sum=;
}
void build(int l,int r,int now){
tr[now].l=l;tr[now].r=r;
if(l==r){
tr[now].gcd=a[l];
tr[now].sum=;
return;
}
int mid=(l+r)>>;
build(l,mid,now*);
build(mid+,r,now*+);
update(now);
}
int getgcd(int l,int r,int now){
if(tr[now].l==l&&tr[now].r==r){
return tr[now].gcd;
}
int mid=(tr[now].l+tr[now].r)>>;
if(l>mid)return getgcd(l,r,now*+);
else if(r<=mid)return getgcd(l,r,now*);
else {
return gcd(getgcd(l,mid,now*),getgcd(mid+,r,now*+));
}
}
int check(int l,int r,int now){
if(tr[now].l==l&&tr[now].r==r){
if(tr[now].gcd==tmp)return tr[now].sum;
else return ;
}
int mid=(tr[now].l+tr[now].r)>>;
if(l>mid)return check(l,r,now*+);
else if(r<=mid)return check(l,r,now*);
else {
return check(l,mid,now*)+check(mid+,r,now*+);
}
}
int main(){
while(~scanf("%d",&n)){
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
build(,n,);
scanf("%d",&m);
for(int i=,l,r;i<=m;i++){
scanf("%d%d",&l,&r);
tmp=getgcd(l,r,);
printf("%d\n",r-l+-check(l,r,));
}
}
return ;
}
题意:
求区间gcd以及这个区间内的数字等于区间gcd的有多少个(其实是不等于,用区间长度减一下就好了)。
数据范围:1 ≤ n ≤ 105
题解
这题用线段树,但一眼望去这题似乎不满足合并,但实际上是可以的。
我们在线段树上维护两个东西,一个是区间gcd一个是区间中等于区间gcd的数的个数记为sum。
考虑如何合并,如果当前区间的两个字区间gcd相等,那么直接把sum相加就好,如果gcd等于两个gcd中的一个,那么sum就是相等gcd对应的那个,如果不相等,那么sum就为0。
为什么呢?gcd一定小于等于比区间所有数的最小值。gcd合并一定会减少或者不变,不变的话就是第一种情况,减少的话,gcd就比区间的所有数都小,所以区间中就不会有数等于gcd了。
最新文章
- 使用ajax获取JSON数据的jQuery代码的格式
- [Andrew]Ext.Net常用布局(Border布局)
- JS中的for和for in循环
- C#读取网页
- 《Android第一行代码》笔记
- hdu3294(manacher)
- SVN基于Maven的Web项目更新,本地过程详细解释
- 2016大连网络赛 Function
- Image和字节数组互转
- MATLAB垂直搜索图片中的白段
- vs2015 c# winfrom应用程序打包成64位
- cordova本地浮动框提示插件使用:cordova-plugin-x-toast
- Python编程Day7——字符编码、字符与字节、文件操作
- es6学习---.babelrc文件
- CentOS下KVM网卡设置成网桥时获取镜像端口的流量
- javascript显示年月日时间代码
- 【校招面试 之 C/C++】第5题 C++各种构造函数的写法
- android 的helloworld没跑起来 原因
- 20155213 2016-2017-2 《Java程序设计》第七周学习总结
- 需求:过滤下面这个网页里共723行 校对中里 行数为两位数的 行 并设置sz和rz在Windows和Linux之间发送和接收文件不用搭FTP
热门文章
- ZBrush中Local模式的旋转
- luogu P5290 [十二省联考2019]春节十二响 优先队列_启发式合并
- 8、Situation-Dependent Combination of Long-Term and Session-Based Preferences in Group Recommendations: An Experimental Analysis ----组推荐中基于长期和会话偏好的情景依赖组合
- 基础——(4)D Latch(D锁存器)
- node工具是是什么东西
- js 正则表达式 整合
- Codeforces 667B Coat of Anticubism
- 紫书 例题8-2 UVa 11605(构造法)
- navicat连接SQL Sever数据库出现的问题
- POJ 2230 Watchcow