2016 大连网赛---Different GCD Subarray Query(…
2018-06-17 23:47:19来源:未知 阅读 ()
题目链接
http://acm.split.hdu.edu.cn/showproblem.php?pid=5869
Given an array a of N positive integers a1,a2,?aN−1,aN; a subarray of a is defined as a continuous interval between a1 and aN. In other words, ai,ai+1,?,aj−1,aj is a subarray of a, for 1≤i≤j≤N. For a query in the form (L,R), tell the number of different GCDs contributed by all subarrays of the interval [L,R].
For each test, the first line consists of two integers N and Q, denoting the length of the array and the number of queries, respectively. N positive integers are listed in the second line, followed by Q lines each containing two integers L,R for a query.
You can assume that
1≤N,Q≤100000
1≤ai≤1000000
for(int i=1;i<=N;i++) { int tot=a[i],pos=i; for(int j=0;j<v[i-1].size();j++) { int r=__gcd(a[i],v[i-1][j].first); if(tot!=r) { v[i].push_back(make_pair(tot,pos)); tot=r; pos=v[i-1][j].second; } } v[i].push_back(make_pair(tot,pos)); }
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <map> #include <vector> using namespace std; int a[100005]; int c[1000005]; int vis[1000005]; int sum[100005]; struct Node { int l,r; int id; }node[100005]; bool cmp(const Node s1,const Node s2) { return s1.r<s2.r; } vector<pair<int,int> > v[100005]; int __gcd(int x,int y) { int r=x%y; x=y; y=r; if(r==0) return x; return __gcd(x,y); } int Lowbit(int t) { return t&(t^(t-1)); } int Sum(int x) { int sum = 0; while(x > 0) { sum += c[x]; x -= Lowbit(x); } return sum; } void add(int li,int t) { while(li<=1000005) { c[li]+=t; li=li+Lowbit(li); } } int main() { int N,Q; while(scanf("%d%d",&N,&Q)!=EOF) { for(int i=1;i<=N;i++) scanf("%d",&a[i]); for(int i=1;i<=N;i++) { int tot=a[i],pos=i; for(int j=0;j<v[i-1].size();j++) { int r=__gcd(a[i],v[i-1][j].first); if(tot!=r) { v[i].push_back(make_pair(tot,pos)); tot=r; pos=v[i-1][j].second; } } v[i].push_back(make_pair(tot,pos)); } for(int i=0;i<Q;i++) scanf("%d%d",&node[i].l,&node[i].r),node[i].id=i; sort(node,node+Q,cmp); memset(c,0,sizeof(c)); memset(vis,0,sizeof(vis)); int len=0; for(int i=1;i<=N;i++) { for(int j=0;j<v[i].size();j++) { int s1=v[i][j].first; int s2=v[i][j].second; if(vis[s1]){ add(vis[s1],-1); } vis[s1]=s2; add(s2,1); } while(node[len].r==i) { sum[node[len].id]=Sum(i)-Sum(node[len].l-1); len++; } } for(int i=0;i<Q;i++) printf("%d\n",sum[i]); for(int i=0;i<=N;i++) v[i].clear(); } return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:让任务管理器播放动画
- 2020年3月28日UCF Local Programming Contest 2016 2020-03-31
- 洛谷P4071-[SDOI2016]排列计数 题解 2020-01-12
- [NOIP2016]天天爱跑步-题解 2019-10-08
- CSP201612-2:工资计算 2018-09-05
- CSP201604-2:俄罗斯方块 2018-09-01
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash