• 洛谷P5071 此时此刻的光辉


    2s512M。

    解:先分解质因数。考虑按照质因数大小是否大于√分类。

    大于的就是一个数颜色个数,莫队即可n√m。

    小于的直接枚举质因数做前缀和然后O(1)查询。总时间复杂度n(√m + σ(√V))。

    发现我们T飞了,发现莫队的复杂度较优,而处理小于√V的质因数较劣。我们平衡一下。

    把界调整到1000。这样比lm大的至多两个,莫队常数*2。而后半部分的复杂度就变成了nσ(3√V),可以通过本题。

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 100010, MO = 19260817;
      4 
      5 inline char gc() {
      6     static char *p1, *p2, s[N];
      7     if(p1 == p2) p2 = (p1 = s) + fread(s, 1, N, stdin);
      8     return (p1 == p2) ? EOF : *p1++;
      9 }
     10 
     11 template <class T> inline void read(T &x) {
     12     x = 0;
     13     register char c(gc());
     14     while(c < '0' || c > '9') {
     15         c = gc();
     16     }
     17     while(c >= '0' && c <= '9') {
     18         x = x * 10 + c - 48;
     19         c = gc();
     20     }
     21     return;
     22 }
     23 
     24 int ex[N], p[N], a[N], lc[N], rc[N], fr[N], top, X[N * 2], xx, inv[N], bin[N], Ans, ans[N], sum[N], exx[N];
     25 bool vis[N];
     26 std::vector<int> v[N], v2[N];
     27 
     28 struct Node {
     29     int l, r, id;
     30     inline bool operator < (const Node &w) const {
     31         if(fr[l] != fr[w.l]) return l < w.l;
     32         return r < w.r;
     33     }
     34 }node[N];
     35 
     36 inline void getp(int n) {
     37     for(register int i = 2; i <= n; i++) {
     38         if(!vis[i]) p[++top] = i;
     39         for(int j = 1; j <= top && i * p[j] <= n; j++) {
     40             vis[i * p[j]] = 1;
     41             if(i % p[j] == 0) break;
     42         }
     43     }
     44     return;
     45 }
     46 
     47 inline void add(int y) {
     48     if(ex[y]) {
     49         int x(ex[y]);
     50         if(bin[x]) {
     51             Ans = 1ll * Ans * inv[bin[x] + 1] % MO;
     52         }
     53         ++bin[x];
     54         Ans = 1ll * Ans * (bin[x] + 1) % MO;
     55     }
     56     if(exx[y]) {
     57         int x(exx[y]);
     58         if(bin[x]) {
     59             Ans = 1ll * Ans * inv[bin[x] + 1] % MO;
     60         }
     61         ++bin[x];
     62         Ans = 1ll * Ans * (bin[x] + 1) % MO;
     63     }
     64     return;
     65 }
     66 
     67 inline void del(int y) {
     68     if(ex[y]) {
     69         int x(ex[y]);
     70         Ans = 1ll * Ans * inv[bin[x] + 1] % MO;
     71         --bin[x];
     72         if(bin[x]) {
     73             Ans = 1ll * Ans * (bin[x] + 1) % MO;
     74         }
     75     }
     76     if(exx[y]) {
     77         int x(exx[y]);
     78         Ans = 1ll * Ans * inv[bin[x] + 1] % MO;
     79         --bin[x];
     80         if(bin[x]) {
     81             Ans = 1ll * Ans * (bin[x] + 1) % MO;
     82         }
     83     }
     84     return;
     85 }
     86 
     87 inline void solve(int x) {
     88     printf("div : %d 
    ", x);
     89     for(int i = 1; i <= top; i++) {
     90         if(x % p[i]) continue;
     91         while(x % p[i] == 0) {
     92             printf("%d ", p[i]);
     93             x /= p[i];
     94         }
     95     }
     96     if(x > 1) printf("%d ", x);
     97     puts("");
     98     return;
     99 }
    100 
    101 int main() {
    102     getp(31623);
    103 
    104     register int n, m, lm(1000);
    105     //scanf("%d%d", &n, &m);
    106     read(n), read(m);
    107     int T = n / sqrt(m);
    108     for(register int i(1); i <= n; ++i) {
    109         //scanf("%d", &a[i]);
    110         read(a[i]);
    111         fr[i] = (i - 1) / T + 1;
    112         register int x(a[i]), j(1);
    113         for(; p[j] <= lm && p[j] <= x; ++j) {
    114             register int cnt(0);
    115             while(x % p[j] == 0) {
    116                 x /= p[j];
    117                 ++cnt;
    118             }
    119             if(cnt) {
    120                 v[j].push_back(i);
    121                 v2[j].push_back(cnt);
    122             }
    123         }
    124         if(x == 1) continue;
    125         for(; j <= top; j++) {
    126             if(x % p[j] == 0) {
    127                 exx[i] = p[j];
    128                 X[++xx] = p[j];
    129                 x /= p[j];
    130                 break;
    131             }
    132         }
    133         if(x > 1) {
    134             ex[i] = x;
    135             X[++xx] = x;
    136         }
    137     }
    138 
    139     std::sort(X + 1, X + xx + 1);
    140     xx = std::unique(X + 1, X + xx + 1) - X - 1;
    141     for(register int i(1); i <= n; ++i) {
    142         //printf("i = %d : %d %d 
    ", i, ex[i], exx[i]);
    143         if(ex[i]) {
    144             ex[i] = std::lower_bound(X + 1, X + xx + 1, ex[i]) - X;
    145         }
    146         if(exx[i]) {
    147             exx[i] = std::lower_bound(X + 1, X + xx + 1, exx[i]) - X;
    148         }
    149     }
    150 
    151     for(register int i(1); i <= m; ++i) {
    152         //scanf("%d%d", &node[i].l, &node[i].r);
    153         read(node[i].l); read(node[i].r);
    154         node[i].id = i;
    155     }
    156     inv[0] = inv[1] = 1;
    157     for(register int i(2); i <= n + 1; ++i) {
    158         inv[i] = 1ll * inv[MO % i] * (MO - MO / i) % MO;
    159     }
    160 
    161     for(register int i(1); i <= fr[n]; ++i) {
    162         lc[i] = rc[i - 1] + 1;
    163         rc[i] = lc[i] + T - 1;
    164         if(i == fr[n]) rc[i] = n;
    165     }
    166 
    167     std::sort(node + 1, node + m + 1);
    168 
    169     Ans = 1;
    170     add(1);
    171     int l = 1, r = 1;
    172     for(register int i = 1; i <= m; i++) {
    173         while(r < node[i].r) {
    174             add(++r);
    175         }
    176         while(node[i].l < l) {
    177             add(--l);
    178         }
    179         while(node[i].r < r) {
    180             del(r--);
    181         }
    182         while(l < node[i].l) {
    183             del(l++);
    184         }
    185         ans[node[i].id] = Ans;
    186         //printf("ans %d = %d 
    ", node[i].id, Ans);
    187     }
    188 
    189     /// step 2
    190 
    191     for(register int i(1); p[i] <= lm; ++i) {
    192         int LEN(v[i].size()), p(0);
    193         for(register int j(1); j <= n; ++j) {
    194             sum[j] = sum[j - 1];
    195             if(p < LEN && v[i][p] == j) {
    196                 sum[j] += v2[i][p++];
    197             }
    198         }
    199         for(register int j(1); j <= m; ++j) {
    200             int x = sum[node[j].r] - sum[node[j].l - 1];
    201             ans[node[j].id] = 1ll * ans[node[j].id] * (x + 1) % MO;
    202         }
    203     }
    204 
    205     for(register int i(1); i <= m; ++i) {
    206         printf("%d
    ", ans[i]);
    207     }
    208 
    209     return 0;
    210 }
    AC代码
  • 相关阅读:
    MySQL之索引
    MySQL之用户权限及pymysql
    Vue初识
    input标签的accept属性、JQuery绑定keyDown事件
    给bootstrap-sweetalert弹框的按钮绑定事件
    JavaScript FormData对象,FileReader对象,files属性
    Django CBV加装饰器、Django中间件、auth模块
    Django session和cookie
    Django form组件
    Django ajax的简单使用、自定义分页器
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10896966.html
Copyright © 2020-2023  润新知