题目描述:
线段树操作.有两种不同的操作,a.一个是将l到r的加上一个等差数列.b.另一个是把l到r的数都改成x.查询是查询l到r的和.
题解:
两个标签的线段树,关键是要确定标签的先后顺序.我们定的是先b再a.就是说:如果有b和a的标签同时都有的话,那么我的顺序是先处理b,再处理a.如果一个点什么都没有,那么就随便加标签,如果有a标签,再加b标签,我会先把a标签传下去,再加b标签.如果现有b标签,我加a标签就加了.不会影响. 查询的时候,同时有a和b的话,先传递下去b,然后再传递下去a.
重点:
定义好标签的先后顺序
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l,m,k<<1
#define rson m+1,r,k<<1|1
typedef long long ll;
const int N = 250010;
struct T
{
ll st,d,s;
int tagtag,sttag;
ll tag;
ll sum;
}f[N<<2];
int n;
void put(int k,ll sst,ll dd)
{
f[k].sum += (sst + (f[k].s - 1) * dd + sst) * f[k].s / 2;
}
void down(int k)
{
if (f[k].tagtag > 0)
{
f[k<<1].tag = f[k<<1|1].tag = f[k].tag;
f[k<<1].tagtag = f[k<<1|1].tagtag = 1;
f[k<<1].st = f[k<<1].d = f[k<<1].sttag = 0;
f[k<<1|1].st = f[k<<1|1].d = f[k<<1|1].sttag = 0;
f[k<<1].sum = f[k<<1].s * f[k<<1].tag;
f[k<<1|1].sum = f[k<<1|1].s * f[k<<1|1].tag;
f[k].tagtag = f[k].tag = 0;
}
if (f[k].sttag > 0)
{
if (f[k<<1].tagtag)
{
//f[k<<1].st += f[k<<1].tag;
//f[k<<1].tagtag = f[k<<1].tag = 0;
}
f[k<<1].st += f[k].st; f[k<<1].d += f[k].d;
put(k<<1,f[k].st,f[k].d);
if (f[k<<1|1].tagtag)
{
//f[k<<1|1].st += f[k<<1|1].tag;
//f[k<<1|1].tagtag = f[k<<1|1].tag = 0;
}
f[k<<1|1].st += f[k].st + f[k].d * f[k<<1].s; f[k<<1|1].d += f[k].d;
put(k<<1|1,f[k].st + f[k].d * f[k<<1].s,f[k].d);
f[k].st = f[k].d = f[k].sttag = 0;
f[k<<1].sttag = f[k<<1|1].sttag = 1;
}
}
void up(int k)
{
f[k].sum = f[k<<1].sum + f[k<<1|1].sum;
}
void mk(int l,int r,int k)
{
f[k].s = r - l + 1;
f[k].sttag = 0;
f[k].tagtag = f[k].sum = f[k].tag = f[k].st = f[k].d = 0;
if (l == r)
{
return;
}
int m = (l + r) >> 1;
mk(lson);
mk(rson);
//up(k);
}
void update1(int la,int ra,int l,int r,int k,ll st,ll d)
{
if (la <= l && r <= ra)
{
if (f[k].tagtag)
{
//f[k].st += f[k].tag;
}
//f[k].tagtag = f[k].tag = 0;
ll sst = st + (l - la) * d;
f[k].sum += (sst + (f[k].s - 1) * d + sst) * f[k].s / 2;
f[k].st += sst;
f[k].d += d;
f[k].sttag = 1;
return;
}
down(k);
int m = (l + r) >> 1;
if (la <= m) update1(la,ra,lson,st,d);
if (m < ra) update1(la,ra,rson,st,d);
up(k);
}
void update2(int la,int ra,int l,int r,int k,int d)
{
if (la <= l && r <= ra)
{
f[k].tagtag = 1;
f[k].tag = d;
f[k].st = f[k].d = 0;
f[k].sum = f[k].s * f[k].tag;
f[k].sttag = 0;
return;
}
down(k);
int m = (l + r) >> 1;
if (la <= m) update2(la,ra,lson,d);
if (m < ra) update2(la,ra,rson,d);
up(k);
}
ll query(int la,int ra,int l,int r,int k)
{
if (la <= l && r <= ra)
{
// put(k);
return f[k].sum;
}
down(k);
ll res = 0;
int m = (l + r) >> 1;
if (la <= m) res += query(la,ra,lson);
if (m < ra) res += query(la,ra,rson);
up(k);
return res;
}
int main()
{
// freopen("in.txt","r",stdin);
n = 250000;
int t;
while (~scanf("%d",&t))
{
mk(1,n,1);
//printf("%I64d\n",query(1,n,1,n,1));
for (int i = 1;i <= t;i++)
{
int a,b,c;
char ch[10];
scanf("%s",ch);
if (ch[0] == 'A')
{
scanf("%d %d",&a,&b);
update1(a,b,1,n,1,1,1);
}
if (ch[0] == 'B')
{
scanf("%d %d",&a,&b);
update1(a,b,1,n,1,b-a+1,-1);
}
if (ch[0] == 'C')
{
scanf("%d %d %d",&a,&b,&c);
update2(a,b,1,n,1,c);
}
if (ch[0] == 'S')
{
scanf("%d %d",&a,&b);
printf("%lld\n",query(a,b,1,n,1));
}
//printf("%I64d\n",f[212645].sum);
}
//printf("%I64d\n",f[2].sum);
}
}