codeforces 475D
来源:互联网 发布:linux cpu wait sys 编辑:程序博客网 时间:2024/04/29 05:06
http://www.cnblogs.com/yzcstc/p/4008199.html
题意:给定n(n<=100000)个1e9以内的数的数组a,然后最多有3*1e5的询问,对于每个询问,给定一个x,问有多少个(l<=r&&gcd(a[l],a[l+1]...a[r]) == x)
思路:昨天的比赛题。。可惜我被c题wa到放弃了这场比赛。。也就没看了。。不妨设G(l,r) = gcd(a[l], a[l+1]...a[r]);
其实题目最关键的的性质是对于G(l,r),G(l,r+1)后者肯定比前者更小。。
所以就可以暴力了。。从后往前扫描i,处理(i, n)这一段区间,处理处理完之后,就会出现G(i,i),G(i,i+1)..G(i, n),并且是递减的
所以相邻之间如果相同,我们就可以合并,具体操作可以用链表。。
这样最坏情况下每个数求log(1e9)次gcd,所以还是可以快速过的。。
code:
#include <bits/stdc++.h>using namespace std;int a[101010], nxt[101010], n;map<int, long long> mp;void solve(){ for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), nxt[i] = i + 1; mp.clear(); for (int i = n; i >= 1; --i){ int g = a[i], pre_g = g, pre = i; for (int j = i; j <= n + 1; j = nxt[j]){ if (j == n + 1){ mp[pre_g] += (j - pre); nxt[pre] = j; break; } g = __gcd(a[j], g); if (g != pre_g) mp[pre_g] += (j - pre) , nxt[pre] = j , pre = j, pre_g = g; } } int q, x; scanf("%d", &q); while (q--){ scanf("%d", &x); printf("%I64d\n",mp[x]); }}int main(){ while (scanf("%d", &n) != EOF){ solve(); }}
0 0
- 【codeforces】 475D CGCDSSQ
- Codeforces 475 D. CGCDSSQ
- CodeForces 475D CGCDSSQ
- codeforces 475D
- CodeForces 475D CGCDSSQ
- CodeForces 475D CGCDSSQ RMQ
- Codeforces 475D CGCDSSQ 题解
- codeforces 475D CGCDSSQ ST表+二分
- CodeForces 617D CodeForces 617D
- CodeForces 101D
- CodeForces 103D
- CodeForces 222D Olympiad
- codeforces 242d
- CodeForces 111D
- 【codeforces】3D
- CodeForces 127D Password
- codeforces 257D. Sum
- Codeforces 292D
- shell学习
- myeclipse中disable maven nature如何恢复
- 2014-11-6Android学习------activity切换特效--------动画Animation学习篇
- 第十一周项目1步骤(3)
- 马云是如何用人的?
- codeforces 475D
- Detector 检测内存泄露
- linux学习之十三---多线程的创建
- 关于struts2配置struts.devMode问题解释
- LINUX 查看分区UUID的两种方法
- JAVA: httpclient 详解——第一章;
- 米聊
- [HDU 1087]Super Jumping! Jumping! Jumping!(类LIS DP)
- jQuery中的选择器