码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 475D

时间:2014-10-06 17:41:30      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   ar   for   数据   sp   

题意:给定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),并且是递减的

       所以相邻之间如果相同,我们就可以合并,具体操作可以用链表。。

       虽然这样不好算实际的复杂度,但是因为数最大为1e9,所以也很难构造卡的数据吧,还是可以快速过的。。

 

code:

bubuko.com,布布扣
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a[101010], nxt[101010], n;
 4 map<int, long long> mp;
 5 
 6 void solve(){
 7      for (int i = 1; i <= n; ++i)
 8           scanf("%d", &a[i]), nxt[i] = i + 1;
 9      mp.clear();
10      for (int i = n; i >= 1; --i){
11           int g = a[i], pre_g = g, pre = i;
12           for (int j = i; j <= n + 1; j = nxt[j]){
13                  if (j == n + 1){
14                          mp[pre_g] += (j - pre); 
15                          nxt[pre] = j;
16                          break;
17                  }
18                  g = __gcd(a[j], g);
19                  if (g != pre_g)
20                          mp[pre_g] += (j - pre) , nxt[pre] = j , pre = j, pre_g = g;
21           }
22      }
23      int q, x;
24     scanf("%d", &q);
25     while (q--){
26           scanf("%d", &x);
27           printf("%I64d\n",mp[x]);
28     }
29 }
30 
31 int main(){
32      while (scanf("%d", &n) != EOF){
33             solve();
34      }
35 }
View Code

 

codeforces 475D

标签:style   blog   http   color   os   ar   for   数据   sp   

原文地址:http://www.cnblogs.com/yzcstc/p/4008199.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!