题目:给个n给个m,给n个数,接下来m个指令,有两种指令,第一种让输出区间a到b的和,第二种把a到b的数改成c
线段树板子题,开始写的时候不知道有延迟标记,然后疯狂T
#include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <string> #include <map> #include <iomanip> #include <algorithm> #include <queue> #include <stack> #include <set> #include <vector> //const int maxn = 1e5+5; #define ll long long ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} #define MAX INT_MAX #define FOR(i,a,b) for( int i = a;i <= b;++i) #define bug cout<<"--------------"<<endl using namespace std; ll a[110000]; struct SegmentTree { ll l,r; ll sum; ll add; #define l(x) tree[x].l #define r(x) tree[x].r #define sum(x) tree[x].sum #define add(x) tree[x].add }tree[110000*4]; void build(ll p,ll l,ll r) { l(p) = l,r(p)=r; //===================================== if(l == r) {sum(p)=a[l] ;return ;} ll mid=(l+r)/2; build(p*2, l,mid); build(p*2+1 , mid+1,r); sum(p)+=sum(p*2)+sum(p*2+1); } void spread(ll p) { if(add(p)) { //==================================================== sum(p*2)+=add(p) * (r(p*2)-l(p*2)+1); sum(p*2+1)+= add(p) * (r(p*2+1)-l(p*2+1)+1); add(p*2)+=add(p); add(p*2+1)+=add(p); add(p)=0; } } void change(ll p,ll l,ll r,ll d ) { if(l<=l(p) && r>=r(p)) { sum(p)+=(ll )d * (r(p)-l(p)+1); add(p) +=d; return ; } spread(p); ll mid = (l(p)+r(p))/2; if(l<=mid) change(p*2 , l, r, d); if(r>mid) change(p*2+1,l,r,d); sum(p) = sum(p*2)+sum(p*2+1); } ll ask(ll p,ll l,ll r) { if(l<=l(p) && r>=r(p) ) return sum(p); spread(p); ll mid = (l(p)+r(p))/2; ll val=0; if(l<=mid) val+=ask(p*2,l,r); if(r>mid) val+=ask(p*2+1,l,r); return val; } int main() { ll n,m; cin>>n>>m; FOR(i,1,n) cin>>a[i]; build(1,1,n); char c; while (m--) { char op[2]; int x, y, z; scanf("%s%d%d", op, &x, &y); if (op[0] == 'C') { scanf("%d", &z); change(1, x, y, z); } else printf("%lld ", ask(1, x, y)); } }