首页 > 代码库 > codeforces 475D
codeforces 475D
题意:给定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:
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 }
codeforces 475D
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。