链接:https://ac.nowcoder.com/acm/contest/892/D
来源:牛客网
题目描述
给你一个长度为n的序列,初始为1,2,3...n,对其进行m次操作。
操作有两种:
1 l r 表示将区间[l,r]用 [1,2...r-l+1] 覆盖
2 l r 查询[l,r]的区间和
输入描述:
第一行包含2个数字,n,m(1 <= n,m <= 1e5) 接下来包含m行,格式如题面所示
输出描述:
对于每个操作2,输出一行一个整数表示答案
示例1
输入
复制
10 5 2 1 10 1 3 6 2 1 10 1 1 10 2 1 10
输出
复制
55 47 55
思路:板子题,一个区间修改成前一个区间的值然后求和减去付的值就是这个区间的修改值
#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const ll maxn=1e5+5;
const ll inf=0x3f3f3f3f;
ll laze[maxn<<2],sum[maxn<<2];
void push_up(ll rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push_down(ll rt,ll l,ll r)
{
if(laze[rt]!=-1)
{
ll val=laze[rt];
ll m=(l+r)/2;
laze[rt<<1]=val;
sum[rt<<1]=val*(m-l+1);
laze[rt<<1|1]=val;
sum[rt<<1|1]=val*(r-m);
laze[rt]=-1;
}
}
void bulid(ll rt,ll l,ll r)
{
laze[rt]=-1;
if(l==r)
{
sum[rt]=0;
return ;
}
ll m=l+r>>1;
bulid(lson);
bulid(rson);
push_up(rt);
}
void update(ll L,ll R,ll val,ll rt,ll l,ll r)
{
if(L<=l&&R>=r)
{
laze[rt]=val;
sum[rt]=(r-l+1)*val;
return ;
}
push_down(rt,l,r);
ll m=l+r>>1;
if(L<=m)
update(L,R,val,lson);
if(R>m)
update(L,R,val,rson);
push_up(rt);
}
ll query(ll L,ll R,ll rt,ll l,ll r)
{
if(L<=l&&R>=r){
return sum[rt];
}
push_down(rt,l,r);
ll m=l+r>>1,ans=0;
if(L<=m)
ans+=query(L,R,lson);
if(R>m)
ans+=query(L,R,rson);
push_up(rt);
return ans;
}
int main()
{
ll n,m;
scanf("%lld%lld",&n,&m);
ll l,r,sum;
bulid(1,1,n);
for(int i = 0;i < m;++i)
{
scanf("%lld%lld%lld",&sum,&l,&r);
if(sum == 1)
{
update(l,r,l-1,1,1,n);
}
else{
ll sum = query(l,r,1,1,n);
printf("%lld\n",(l+r)*(r-l+1)/2-sum);
}
}
return 0;
}