Sum HDU - 4407
题面
题解
就是容斥, 主要是细节处理问题
for (auto j : st) {
if (j.fi > r || j.fi < l) continue;
if (__gcd(j.fi, p) == 1) ans -= j.fi;
if (__gcd(j.se, p) == 1) ans += j.se;
}
要弄清上面的逻辑关系, 并且要用map存, 不然多次改动, 要取最后一次
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef pair<ll, int> PLI;
typedef vector<int> VI;
typedef double db;
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
const int N = 4e5 + 5;
int n, m, _, k;
void getf(VI &a, int n) {
rep (i, 2, n / i)
if (n % i == 0) {
a.emplace_back(i);
while (n % i == 0) n /= i;
}
if (n - 1) a.emplace_back(n);
}
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n >> m; unordered_map<ll, ll> st;
rep (i, 1, m) {
cin >> k;
if (k == 1) {
ll l, r, p; cin >> l >> r >> p;
VI fac; getf(fac, p); ll ans = (r + l) * (r - l + 1) / 2;
rep (j, 1, (1 << fac.size()) - 1) {
int cnt = 0, c = 1;
rep (q, 0, fac.size() - 1) if (j >> q & 1) ++cnt, c *= fac[q];
if (cnt & 1) ans -= ((r / c - (l - 1) / c) * (1 + r / c + (l - 1) / c) / 2) * c;
else ans += ((r / c - (l - 1) / c) * (1 + r / c + (l - 1) / c) / 2) * c;
}
for (auto j : st) {
if (j.fi > r || j.fi < l) continue;
if (__gcd(j.fi, p) == 1) ans -= j.fi;
if (__gcd(j.se, p) == 1) ans += j.se;
}
cout << ans << '\n';
} else {
int x, c; cin >> x >> c;
st[x] = c;
}
}
}
return 0;
}