zoukankan      html  css  js  c++  java
  • [美团 CodeM 初赛 Round A]数列互质

    题目大意:
      给出一个长度为n的数列a1,a2,a3,...,an,以及m组询问(li,ri,ki),求区间[li,ri]中有多少数在该区间中的出现次数与ki互质。

    思路:
      莫队。
      f[i]记录数字i出现的次数,用一个链表记录f[i]的出现次数。
      一开始没用链表,用map,在SimpleOJ上随便A,但是在LOJ上只有50分。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=50001,M=50000;
    13 int a[N],f[N],ans[M],block;
    14 struct Question {
    15     int l,r,k,id;
    16     bool operator < (const Question &another) const {
    17         return l/block==another.l/block?r/block<another.r/block:l/block<another.l/block;
    18     }
    19 };
    20 Question q[M];
    21 struct List {
    22     int val[N],last[N],next[N],end;
    23     int &operator [] (const int &p) {
    24         return val[p];
    25     }
    26     void insert(const int &x) {
    27         next[end]=x;
    28         last[x]=end;
    29         end=x;
    30     }
    31     void erase(const int &x) {
    32         if(x==end) end=last[x];
    33         next[last[x]]=next[x];
    34         last[next[x]]=last[x];
    35         val[x]=last[x]=next[x]=0;
    36     }
    37 };
    38 List list;
    39 inline void insert(const int &x) {
    40     if(f[x]&&!--list[f[x]]) list.erase(f[x]);
    41     if(!list[++f[x]]) list.insert(f[x]);
    42     list[f[x]]++;
    43 }
    44 inline void erase(const int &x) {
    45     if(!--list[f[x]]) list.erase(f[x]);
    46     if(--f[x]) {
    47         if(!list[f[x]]) list.insert(f[x]);
    48         list[f[x]]++;
    49     }
    50 }
    51 int gcd(const int &a,const int &b) {
    52     return b?gcd(b,a%b):a;
    53 }
    54 int main() {
    55     const int n=getint(),m=getint();
    56     block=sqrt(m);
    57     for(register int i=1;i<=n;i++) a[i]=getint();
    58     for(register int i=0;i<m;i++) {
    59         q[i]=(Question){getint(),getint(),getint(),i};
    60     }
    61     std::sort(&q[0],&q[m]);
    62     for(register int i=0,l=1,r=0;i<m;i++) {
    63         while(l>q[i].l) insert(a[--l]);
    64         while(r<q[i].r) insert(a[++r]);
    65         while(l<q[i].l) erase(a[l++]);
    66         while(r>q[i].r) erase(a[r--]);
    67         for(register int j=list.end;j;j=list.last[j]) {
    68             if(gcd(j,q[i].k)==1) ans[q[i].id]+=list[j];
    69         }
    70     }
    71     for(register int i=0;i<m;i++) {
    72         printf("%d
    ",ans[i]);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    黄宗禹9.11作业
    黄宗禹第一次作业
    9.11
    9.18
    计算平均速度
    圆的周长与面积
    JAVA 作业
    9.11
    9.25
    计算平均速度题
  • 原文地址:https://www.cnblogs.com/skylee03/p/8124949.html
Copyright © 2011-2022 走看看