区间乘区间加区间询问
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
struct Node{
int l,r;
long long sum;
long long mut,add;
}tr[N << 2];
int a[N];
long long p;
void pushup(int u){
tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % p;
}
void pushdown(int u){
tr[u << 1].sum = (tr[u << 1].sum * tr[u].mut % p + tr[u].add * (tr[u << 1].r - tr[u << 1].l + 1) % p) % p;
tr[u << 1].add = (tr[u << 1].add * tr[u].mut % p + tr[u].add) % p;
tr[u << 1].mut = (tr[u << 1].mut * tr[u].mut) % p;
tr[u << 1 | 1].sum = (tr[u << 1 | 1].sum * tr[u].mut + tr[u].add * (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1) % p) % p;
tr[u << 1 | 1].add = (tr[u << 1 | 1].add * tr[u].mut % p + tr[u].add) % p;
tr[u << 1 | 1].mut = (tr[u << 1 | 1].mut * tr[u].mut) % p;
tr[u].add = 0;
tr[u].mut = 1;
}
void build(int u,int l,int r){
tr[u].l = l;
tr[u].r = r;
tr[u].mut = 1;
if(l == r){
tr[u].sum = a[l];
return;
}
int mid = l + r >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
pushup(u);
}
void modify1(int u,int l,int r,int t){
if(l <= tr[u].l && tr[u].r <= r){
tr[u].add = (tr[u].add * t) % p;
tr[u].mut = (tr[u].mut * t) % p;
tr[u].sum = (tr[u].sum * t) % p;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify1(u << 1,l,r,t);
if(r > mid) modify1(u << 1 | 1,l,r,t);
pushup(u);
}
void modify2(int u,int l,int r,int t){
if(l <= tr[u].l && tr[u].r <= r){
tr[u].add = (tr[u].add + t) % p;
tr[u].sum = (tr[u].sum + (tr[u].r - tr[u].l + 1) * t) % p;
return;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify2(u << 1,l,r,t);
if(r > mid) modify2(u << 1 | 1,l,r,t);
pushup(u);
}
long long query(int u,int l,int r){
if(l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
long long sum = 0;
if(l <= mid) sum = query(u << 1,l,r);
if(r > mid) sum = (sum + query(u << 1 | 1,l,r)) % p;
return sum;
}
int main(){
int n,m;
cin >> n >> p;
for(int i = 1;i <= n;i ++) scanf("%d",&a[i]);
build(1,1,n);
cin >> m;
for(int i = 1;i <= m;i ++){
int k;
scanf("%d",&k);
if(k == 1){
int l,r,t;
scanf("%d%d%d",&l,&r,&t);
modify1(1,l,r,t);
}
if(k == 2){
int l,r,t;
scanf("%d%d%d",&l,&r,&t);
modify2(1,l,r,t);
}
if(k == 3){
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,l,r));
}
}
return 0;
}
无需pushdown的扫描线
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
struct query{
double x,y1,y2;
int k;
bool operator <(const query &t) const{
return x < t.x;
};
}q[N << 1];
struct Node{
int l,r;
int cnt;
double len;
}tr[N << 3];
vector <double> vs;
int find(double y){
return lower_bound(vs.begin(),vs.end(),y) - vs.begin();
}
void build(int u,int l,int r){
if(l == r){
tr[u] = {l,r,0,0};
}else{
tr[u] = {l,r,0,0};
int mid = l + r >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
}
}
void pushup(int u){
if(tr[u].cnt) tr[u].len = vs[tr[u].r + 1] - vs[tr[u].l];
else if(tr[u].l != tr[u].r) tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
else tr[u].len = 0;
}
void modify(int u,int l,int r,int k){
if(l <= tr[u].l && tr[u].r <= r){
tr[u].cnt += k;
pushup(u);
}else{
int mid = tr[u].l + tr[u].r >> 1;
if(l <= mid) modify(u << 1,l,r,k);
if(r > mid) modify(u << 1 | 1,l,r,k);
pushup(u);
}
}
int main(){
int n;
int T = 1;
while(scanf("%d",&n),n){
vs.clear();
for(int i = 1,j = 0;i <= n;i ++){
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
q[++ j] = {x1,y1,y2,1};
q[++ j] = {x2,y1,y2,-1};
vs.push_back(y1);
vs.push_back(y2);
}
sort(vs.begin(),vs.end());
vs.erase(unique(vs.begin(),vs.end()),vs.end());
build(1,0,vs.size() - 2);
sort(q + 1,q + 2 * n + 1);
double res = 0;
for(int i = 1;i <= 2 * n;i ++){
if(i > 1) res += tr[1].len * (q[i].x - q[i - 1].x);
modify(1,find(q[i].y1),find(q[i].y2) - 1,q[i].k);
}
printf("Test case #%d\n",T ++);
printf("Total explored area: %.2lf \n\n",res);
}
return 0;
}