如果没有AC来找我100%AC!!!!!
2025-10-26 15:05:50
发布于:北京
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
using ll = long long;
struct Node {
ll l, r;
mutable ll A, B, start_t; // start_t: 区间左端点对应的原始t值
Node(ll l, ll r = 0, ll A = 0, ll B = 0, ll start_t = 0) :
l(l), r(r), A(A), B(B), start_t(start_t) {}
bool operator<(const Node& other) const {
return l < other.l;
}
};
set<Node> odt;
// 类欧几里得: sum_{t=0}^{n} floor((a*t+b)/c)
ll floor_sum(ll a, ll b, ll c, ll n) {
if (n < 0) return 0;
if (a == 0) {
return (b / c) * (n + 1);
}
if (a >= c || b >= c) {
return floor_sum(a % c, b % c, c, n) +
(a / c) * (n * (n + 1) / 2) +
(b / c) * (n + 1);
}
ll m = (a * n + b) / c;
return n * m - floor_sum(c, c - b - 1, a, m - 1);
}
// 计算区间和:t从start_t到start_t+len-1的(A*t mod B)的和
ll range_sum(ll A, ll B, ll start_t, ll len) {
if (len <= 0) return 0;
if (B == 0) return 0; // 避免除0
// 第一部分:A * sum(t)
ll sum_t = len * start_t + len * (len - 1) / 2;
ll part1 = A * sum_t;
// 第二部分:B * sum(floor(A*t/B))
ll sum_floor = floor_sum(A, 0, B, start_t + len - 1) -
floor_sum(A, 0, B, start_t - 1);
ll part2 = B * sum_floor;
return part1 - part2;
}
auto split(ll pos) {
auto it = odt.lower_bound(Node(pos));
if (it != odt.end() && it->l == pos) return it;
--it;
ll l = it->l, r = it->r, A = it->A, B = it->B, start_t = it->start_t;
odt.erase(it);
odt.insert(Node(l, pos - 1, A, B, start_t));
return odt.insert(Node(pos, r, A, B, start_t + (pos - l))).first;
}
void assign(ll l, ll r, ll A, ll B) {
auto itr = split(r + 1), itl = split(l);
odt.erase(itl, itr);
// 新区间从t=1开始
odt.insert(Node(l, r, A, B, 1));
}
ll query(ll l, ll r) {
auto itr = split(r + 1), itl = split(l);
ll res = 0;
for (auto it = itl; it != itr; ++it) {
ll len = it->r - it->l + 1;
if (it->B == 0) {
// 没有模运算,直接等差数列
res += it->A * (it->start_t * len + len * (len - 1) / 2);
} else {
res += range_sum(it->A, it->B, it->start_t, len);
}
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
ll n, q;
cin >> n >> q;
// 初始整个区间为0 (B=0表示常值0)
odt.insert(Node(1, n, 0, 0, 0));
while (q--) {
int op;
cin >> op;
if (op == 1) {
ll L, R, A, B;
cin >> L >> R >> A >> B;
assign(L, R, A, B);
} else {
ll L, R;
cin >> L >> R;
cout << query(L, R) << '\n';
}
}
return 0;
}
这里空空如也







有帮助,赞一个