Skip to content

Commit 08eb5a8

Browse files
authored
[20250919] BOJ / D4 / mod와 쿼리 / 권혁준
1 parent 0530f98 commit 08eb5a8

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
```cpp
2+
#pragma GCC optimize("Ofast")
3+
#pragma GCC optimize("unroll-loops")
4+
#include <bits/stdc++.h>
5+
using namespace std;
6+
using ll = long long;
7+
8+
ll N, Q, sq=1359;
9+
pair<ll, ll> seg[262144]{};
10+
ll a[100001]{}, cnt[100001]{}, q1[100001]{};
11+
12+
pair<ll, ll> operator+(pair<ll, ll> a, pair<ll, ll> b) {
13+
return {a.first + b.first, a.second + b.second};
14+
}
15+
16+
void upd(int s, int e, int i, ll v, int n) {
17+
if(s == e) {
18+
seg[n].first += v;
19+
seg[n].second += v*s;
20+
return;
21+
}
22+
int m = (s+e)>>1;
23+
if(i<=m) upd(s,m,i,v,n<<1);
24+
else upd(m+1,e,i,v,(n<<1)+1);
25+
seg[n] = seg[n<<1] + seg[(n<<1)+1];
26+
}
27+
28+
pair<ll, ll> find(int s, int e, int l, int r, int n) {
29+
if(l>r || l>e || r<s) return {0,0};
30+
if(l<=s && e<=r) return seg[n];
31+
int m = (s+e)>>1;
32+
return find(s,m,l,r,n<<1) + find(m+1,e,l,r,(n<<1)+1);
33+
}
34+
35+
int main() {
36+
cin.tie(0)->sync_with_stdio(0);
37+
38+
cin>>N;
39+
for(int i=1;i<=N;i++) {
40+
cin>>a[i];
41+
cnt[a[i]]++;
42+
upd(1,100000,a[i],1,1);
43+
}
44+
45+
for(int i=1;i<sq;i++) for(int j=1;j<=N;j++) q1[i] += a[j] % i;
46+
47+
for(cin>>Q;Q--;) {
48+
int op, i, x;
49+
cin>>op;
50+
if(op == 3) {
51+
cin>>i>>x;
52+
ll prev = a[i];
53+
for(int k=1;k<sq;k++) q1[k] += x%k - prev%k;
54+
cnt[prev]--;
55+
cnt[x]++;
56+
a[i] = x;
57+
upd(1,100000,prev,-1,1);
58+
upd(1,100000,x,1,1);
59+
}
60+
else {
61+
cin>>x;
62+
if(op == 1) {
63+
if(x < sq) cout<<q1[x]<<'\n';
64+
else {
65+
ll ans = 0;
66+
for(int k=1;(k-1)*x<=100000;k++) {
67+
auto [c,s] = find(1,100000,max(1,(k-1)*x), min(100000,k*x-1),1);
68+
ans += s - c*(k-1)*x;
69+
}
70+
cout<<ans<<'\n';
71+
}
72+
}
73+
else {
74+
ll ans = N*x;
75+
if(x <= 4) {
76+
for(int p=1;p<=x;p++) ans -= cnt[p] * (x/p) * p;
77+
}
78+
else {
79+
ans -= cnt[1] * x;
80+
ll prev = x, last = x+1, p = 2;
81+
for(;p<=x/p;p++) {
82+
ll q = x/p;
83+
ll s = find(1,100000,q+1,prev,1).second;
84+
ans -= s*(p-1);
85+
ans -= cnt[p] * q * p;
86+
prev = q;
87+
last = q+1;
88+
}
89+
if(p < last) {
90+
ans -= find(1,100000,p,last-1,1).second*(p-1);
91+
}
92+
}
93+
cout<<ans<<'\n';
94+
}
95+
}
96+
}
97+
98+
}
99+
```

0 commit comments

Comments
 (0)