洛谷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 \n", 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 \n", 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 \n", 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\n", ans[i]);
207     }
208 
209     return 0;
210 }
AC代码

 

posted @ 2019-05-20 22:23  huyufeifei  阅读(193)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

ReadEra 阅读书籍

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜