zoukankan      html  css  js  c++  java
  • 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),并且是递减的

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

           这样最坏情况下每个数求log(1e9)次gcd,所以还是可以快速过的。。

    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
    ",mp[x]);
    28     }
    29 }
    30 
    31 int main(){
    32      while (scanf("%d", &n) != EOF){
    33             solve();
    34      }
    35 }
    View Code
  • 相关阅读:
    linux --- 3 vim 网络 用户 权限 软连接 压缩 定时任务 yum源
    linux --- 2.常用命令 , python3, django安装
    linux --- 1.初始linux
    admin ---11.admin , 展示列表 和 分页
    并发 ---- 6. IO 多路复用
    django基础 -- 10.form , ModelForm ,modelformset
    django基础 -- 9.中间件
    flask基础
    MySQL-数据库增删改查
    面试题目二
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4008199.html
Copyright © 2011-2022 走看看