码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3813 奇数国

时间:2015-03-12 20:32:45      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

即求区间的乘积的欧拉函数模一个数

预处理前60个素数和逆元,用线段树维护区间乘机和每个素数出现的次数(我用了bitset嗯嗯嗯)

于是可以O(sqrt(n))求出欧拉函数

 

技术分享
  1 1
  2 2
  3 3
  4 4
  5 5
  6 6
  7 7
  8 8
  9 9
 10 10
 11 11
 12 12
 13 13
 14 14
 15 15
 16 16
 17 17
 18 18
 19 19
 20 20
 21 21
 22 22
 23 23
 24 24
 25 25
 26 26
 27 27
 28 28
 29 29
 30 30
 31 31
 32 32
 33 33
 34 34
 35 35
 36 36
 37 37
 38 38
 39 39
 40 40
 41 41
 42 42
 43 43
 44 44
 45 45
 46 46
 47 47
 48 48
 49 49
 50 50
 51 51
 52 52
 53 53
 54 54
 55 55
 56 56
 57 57
 58 58
 59 59
 60 60
 61 61
 62 62
 63 63
 64 64
 65 65
 66 66
 67 67
 68 68
 69 69
 70 70
 71 71
 72 72
 73 73
 74 74
 75 75
 76 76
 77 77
 78 78
 79 79
 80 80
 81 81
 82 82
 83 83
 84 84
 85 85
 86 86
 87 87
 88 88
 89 89
 90 90
 91 91
 92 92
 93 93
 94 94
 95 95
 96 96
 97 97
 98 98
 99 99
100 100
101 101
102 102
103 103
104 104
105 105
106 106
107 107
108 108
109 109
110 110
111 111
112 112
113 113
114 114
115 115
116 116
117 117
118 118
119 119
120 120
121 121
122 122
123 123
124 /**************************************************************
125     Problem: 3813
126     User: rausen
127     Language: C++
128     Result: Accepted
129     Time:1644 ms
130     Memory:8624 kb
131 ****************************************************************/
132  
133 #include <cstdio>
134 #include <bitset>
135  
136 using namespace std;
137 typedef long long ll;
138 const int mod = 19961993;
139 const int N = 1e5 + 5;
140  
141 struct segment{
142     ll v;
143     bitset <65> ap;
144 } seg[N << 2];
145  
146 int n, m;
147 ll v;
148 bitset <65> ap;
149 int pr[65], tot;
150 ll inv[65];
151 bool vis[305];
152  
153 inline int read() {
154     int x = 0;
155     char ch = getchar();
156     while (ch < 0 || 9 < ch)
157         ch = getchar();
158     while (0 <= ch && ch <= 9) {
159         x = x * 10 + ch - 0;
160         ch = getchar();
161     }
162     return x;
163 }
164  
165 inline ll pow(ll x, int y) {
166     ll res = 1;
167     while (y) {
168         if (y & 1) res = res * x % mod;
169         x = x * x % mod;
170         y >>= 1;
171     }
172     return res;
173 }
174  
175 void pre_work() {
176     int i, j;
177     for (i = 2; tot <= 60; ++i)
178         if (!vis[i]) {
179             pr[++tot] = i;
180             for (j = i; j <= 300; j += i) vis[j] = 1;
181         }
182     for (i = 1; i <= 60; ++i)
183         inv[i] = 1ll * pow(pr[i], mod - 2) * (pr[i] - 1) % mod;
184 }
185  
186 #define Ls (p << 1)
187 #define Rs (p << 1 | 1)
188 #define mid (l + r >> 1)
189 inline void update(int p) {
190     seg[p].v = seg[Ls].v * seg[Rs].v % mod;
191     seg[p].ap = seg[Ls].ap | seg[Rs].ap;
192 }
193  
194 void seg_build(int p, int l, int r) {
195     if (l == r) {
196         seg[p].v = 3, seg[p].ap[2] = 1;
197         return;
198     }
199     seg_build(Ls, l, mid), seg_build(Rs, mid + 1, r);
200     update(p);
201 }
202  
203 void seg_modify(int p, int l, int r, int pos, int v) {
204     if (l == r) {
205         int i;
206         seg[p].v = v, seg[p].ap.reset();
207         for (i = 1; i <= 60; ++i)
208             if (v % pr[i] == 0) seg[p].ap[i] = 1;
209         return;
210     }
211     if (pos <= mid) seg_modify(Ls, l, mid, pos, v);
212     else seg_modify(Rs, mid + 1, r, pos, v);
213     update(p);
214 }
215  
216 void seg_query(int p, int l, int r, int L, int R) {
217     if (L <= l && r <= R) {
218         v = v * seg[p].v % mod, ap |= seg[p].ap;
219         return;
220     }
221     if (L <= mid) seg_query(Ls, l, mid, L, R);
222     if (mid < R) seg_query(Rs, mid + 1, r, L, R);
223 }
224 #undef mid
225 #undef Ls
226 #undef Rs
227  
228 int main() {
229     int oper, x, y, i;
230     pre_work();
231     n = 1e5;
232     seg_build(1, 1, n);
233     m = read();
234     while (m--) {
235         oper = read(), x = read(), y = read();
236         if (oper) seg_modify(1, 1, n, x, y);
237         else {
238             v = 1, ap.reset();
239             seg_query(1, 1, n, x, y);
240             for (i = 1; i <= 60; ++i)
241                 if (ap[i]) v = v * inv[i] % mod;
242             printf("%lld\n", v);
243         }
244     }
245     return 0;
246 }
View Code

 

BZOJ3813 奇数国

标签:

原文地址:http://www.cnblogs.com/rausen/p/4333260.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!