区间修改部分(y总笔记),想了想,还是分开吧

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

区间修改&&区间查询(要pushdown)

# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N  =5e5+10;
struct Node{
    int l, r;
    LL sum;
    int add;
} tr[N<<2];
int w[N];
int n,m;

void pushup(int u){
    tr[u].sum = tr[u<<1].sum + tr[u<< 1 | 1].sum;
}
void pushdown(int u){
    Node &root = tr[u], &left = tr[u<<1], &right = tr[u<<1|1];
    int add = root.add;
    if(add){
        left.add+=add, left.sum += (LL)(left.r-left.l+1) * add;
        right.add+=add, right.sum += (LL)(right.r-right.l+1) * add;
        root.add=0;
    }
}

void build(int u, int l, int r){
    if(l==r) tr[u]={l,l,w[l], 0};
    else {
        tr[u]={l,r};
        int mid = l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}

void mody(int u, int l, int r, int d){
    if(l<=tr[u].l && tr[u].r <= r){
        tr[u].sum+=(LL)(tr[u].r - tr[u].l +1) * d;
        tr[u].add+=d;
    }else {
        int mid = tr[u].l+tr[u].r>>1;
        pushdown(u);
        if(l<=mid)mody(u<<1,l,r,d);
        if(r>mid) mody(u<<1|1,l,r,d);
        pushup(u);
    }
}

LL query(int u, int l, int r){
    if(l <= tr[u].l && tr[u].r <= r){
        return tr[u].sum;
    }else {
        int mid = tr[u].l+tr[u].r>>1;
        pushdown(u);
        LL sum = 0;
        if(l<=mid)sum+= query(u<<1,l,r);
        if(r>mid) sum+=query(u<<1|1,l,r);
        return sum;
    }
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++ )scanf("%d", w+i);
    build(1,1,n);
    while(m -- ){
        char op[2];
        int l, r;
        int d;
        scanf("%s%d%d", op, &l, &r);
        if(*op=='Q')printf("%lld\n", query(1,l,r));
        else {
            scanf("%d", &d);
            mody(1,l,r,d);
        }
    }
    return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扫描线

# include <bits/stdc++.h>
# define  db double
using namespace std;
const int N =1e5+10;
struct Segment{
    db x, y1, y2;
    int k;
    bool operator < (const Segment& a)const{
        return x<a.x;
    }
} seg[N*2];
struct Node{
    int l,r;
    int cnt;
    double len;
} tr[N<<3];
int n;
vector<db> ys;
int find(db y){
    return lower_bound(ys.begin(),ys.end(),y)-ys.begin();
}

void pushup(int u){
    if(tr[u].cnt) tr[u].len = ys[tr[u].r+1]-ys[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 build(int u, int l, int r){
    if(l==r) tr[u]={l,r,0,0};
    else {
        tr[u]={l,r};
        int mid = l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
    }
}
void mody(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)mody(u<<1,l,r,k);
        if(r>mid)mody(u<<1|1,l,r,k);
        pushup(u);
    }
}
int main(){
    int cas = 0;
    //scanf("%d",&tt);
    while(scanf("%d", &n), n){
       // scanf("%d", &n);
        int cnt = 0;
        for(int i = 1; i <= n; i ++ ){
            db x1,x2,y1,y2;
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            seg[cnt++]={x1,y1,y2,1};
            seg[cnt++]={x2,y1,y2,-1};
            ys.push_back(y1);
            ys.push_back(y2);
        }
        sort(ys.begin(),ys.end());
        ys.erase(unique(ys.begin(),ys.end()),ys.end());
        
        build(1,0,ys.size()-2);
        sort(seg, seg+2*n);
        db res = 0;
        for(int i = 0; i <2*n; i ++ ){
            if(i)res += tr[1].len*(seg[i].x-seg[i-1].x);
            mody(1,find(seg[i].y1),find(seg[i].y2)-1,seg[i].k);
        }
        printf("Test case #%d\n", ++cas);
        printf("Total explored area: %.2f\n\n", res);
    }
    return 0;
}

在这里插入图片描述

乘法&&加法(典型eg)

# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
struct Node{
    int l, r;
    int sum,add,mul;
} tr[N<<2];
int n,m, p;
int w[N];

void pushup(int u){
    tr[u].sum = (tr[u<<1].sum + tr[u<<1|1].sum) % p;
}
void eval(Node& root, int add, int mul){
    root.sum = ((LL)root.sum*mul+(LL)(root.r-root.l+1)*add)%p;//
    root.mul = ((LL)root.mul*mul)%p;
    root.add = ((LL)root.add*mul+add)%p;
}
void pushdown(int u){
    eval(tr[u<<1],tr[u].add,tr[u].mul);
    eval(tr[u<<1|1],tr[u].add,tr[u].mul);
    tr[u].add=0;
    tr[u].mul=1;
}
void build(int u, int l, int r){
    if(l==r)tr[u]={l,r,w[r],0,1};
    else {
        tr[u]={l,r,0,0,1};
        int mid =  l+r >>1;
        build(u<<1,l,mid), build(u<<1|1,mid+1,r);
        pushup(u);
    }
}
void mody(int u, int l, int r, int add, int mul){
    if(l <= tr[u].l && tr[u].r <= r){
        eval(tr[u],add,mul);
    }else {
        int mid=tr[u].l+tr[u].r>>1;
        pushdown(u);
        if(l<=mid) mody(u<<1,l,r,add,mul);
        if(r>mid) mody(u<<1|1,l,r,add,mul);
        pushup(u);
    }
}
int query(int u, int l, int r){
    if(l <= tr[u].l && tr[u].r <= r){
        return tr[u].sum%p;
    }else {
        pushdown(u);
        int mid = tr[u].l+tr[u].r>>1;
        int sum = 0;
        if(l<=mid)sum=query(u<<1,l,r);
        if(r>mid)sum+=query(u<<1|1,l,r);
        return sum%p;
    }
}
int main(){
    scanf("%d%d", &n, &p);
    for(int i = 1; i <=n ; i++)scanf("%d", w+i);
    build(1,1,n);
    scanf("%d",&m);
    while(m--){
        int l,r,c, op;
        scanf("%d%d%d", &op, &l, &r);
        if(op!=3)scanf("%d", &c);
        if(op==1){
            mody(1,l,r,0,c%p);
        }else if(op==2){
            mody(1,l,r,c%p,1);
        }else {
            printf("%d\n", query(1,l,r));
        }
    }
    return 0;
}

作者:HenriHGS
链接:https://www.acwing.com/activity/content/code/content/807230/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值