[CC-ANUGCD]Maximum number, GCD condition

题目大意:

一个长度为\(n(n\le10^5)\)的数列\(A(A_i\le10^5)\),\(m(m\le10^5)\)次询问,每次询问\(l\sim r\)中不与\(g\)互质的数中的最大数以及最大数的个数。

思路:

对于每个质数维护一棵线段树,记录区间内包含这个质数的数的和。询问时将\(g\)分解质因数,在线段树上寻找最大值。

统计个数时将所有数以数值为第一关键字、下标为第二关键字排序后二分即可。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=1e5+1,P=9593;
int p[P];
bool vis[N];
std::pair<int,int> v[N];
inline void sieve() {
for(register int i=2;i<N;i++) {
if(!vis[i]) p[++p[0]]=i;
for(register int j=1;j<=p[0]&&i*p[j]<N;j++) {
vis[i*p[j]]=true;
if(i%p[j]==0) break;
}
}
}
class SegmentTree {
#define mid ((b+e)>>1)
private:
struct Node {
int val;
Node *left,*right;
Node() {
val=-1;
left=right=NULL;
}
};
public:
Node *root;
void modify(Node* &p,const int &b,const int &e,const int &x,const int &y) {
if(!p) p=new Node();
p->val=std::max(p->val,y);
if(b==e) return;
if(x<=mid) modify(p->left,b,mid,x,y);
if(x>mid) modify(p->right,mid+1,e,x,y);
}
int query(const Node* const &p,const int &b,const int &e,const int &l,const int &r) const {
if(!p) return -1;
if(b==l&&e==r) return p->val;
int ret=-1;
if(l<=mid) ret=std::max(ret,query(p->left,b,mid,l,std::min(mid,r)));
if(r>mid) ret=std::max(ret,query(p->right,mid+1,e,std::max(mid+1,l),r));
return ret;
}
#undef mid
};
SegmentTree t[P];
int main() {
sieve();
const int n=getint(),m=getint();
for(register int i=1,b;i<=n;i++) {
v[i].first=b=getint();
v[i].second=i;
for(register int j=1;p[j]*p[j]<=b;j++) {
if(b%p[j]!=0) continue;
while(b%p[j]==0) b/=p[j];
t[j].modify(t[j].root,1,n,i,v[i].first);
}
if(b!=1) {
const int j=std::lower_bound(&p[1],&p[p[0]]+1,b)-p;
t[j].modify(t[j].root,1,n,i,v[i].first);
}
}
std::sort(&v[1],&v[n]+1);
for(register int i=0;i<m;i++) {
int g=getint();
const int l=getint(),r=getint();
int max=-1;
for(register int i=1;p[i]*p[i]<=g;i++) {
if(g%p[i]!=0) continue;
while(g%p[i]==0) g/=p[i];
max=std::max(max,t[i].query(t[i].root,1,n,l,r));
}
if(g!=1) {
const int &i=std::lower_bound(&p[1],&p[p[0]]+1,g)-p;
max=std::max(max,t[i].query(t[i].root,1,n,l,r));
}
const int cnt=std::upper_bound(&v[1],&v[n]+1,std::make_pair(max,r))-std::lower_bound(&v[1],&v[n]+1,std::make_pair(max,l));
printf("%d %d\n",max,cnt?:-1);
}
return 0;
}

最新文章

  1. ajax两张传输数据方式
  2. Java EE之数据库连接与插入
  3. jQuery中bind方法和live方法区别解析
  4. 一次领域驱动设计(DDD)的实际应用
  5. HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
  6. ubuntu10.04共享文件夹
  7. 利用管道实现Shell多进程
  8. Codeforces 374B - Inna and Nine
  9. Linq to OBJECT延时标准查询操作符
  10. mysqldump报错
  11. [转] 关于 Eclipse 导出 Android项目 JavaDoc 详细过程
  12. 原生JS-----论数据类型检测
  13. 爬起点小说 day01
  14. 浅谈React
  15. 【爬虫】在Xpath中使用正则
  16. python第十五天-原来还差一份作业
  17. 026 使用大数据对网站基本指标PV案例的分析
  18. android studio 断网使用
  19. NTP多种模式的配置
  20. [Windows Azure] Windows Azure Web Sites, Cloud Services, and VMs: When to use which?

热门文章

  1. redis中插入用户集合的语句,有四个属性
  2. Android Service使用简单介绍
  3. Windows降权
  4. ELK&amp;ElasticSearch5.1基础概念及配置文件详解【转】
  5. 63.UniquePaths II---dp
  6. 002_让你的linux虚拟终端五彩缤纷(1)——LS颜色设置
  7. 服务号使用微信网页授权(H5应用等)
  8. 用PHP去实现数据库查询结果缓存
  9. php返回json数据函数实例_php技巧_脚本之家
  10. csu 1550(字符串处理思路题)