1080 : 更为复杂的买卖房屋姿势
http://hihocoder.com/problemset/problem/1080
题面蛮好玩的,,也行是因为我玩模拟城市的缘故
修模板了
带两个操作的话,注意set和tag的顺序
每次down的时候先放set标记,再放tag标记
每次更新set的时候要把tag清空
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N =260000;
int n,m;
struct linetree{
#define lc (t<<1)
#define rc (t<<1^1)
#define mid (l[t]+r[t]>>1)
int l[N],r[N],M,tag[N],sum[N],len[N],Set[N];
inline void build(int n){
M=1; while(M<n)M<<=1; M--;//get M
memset(sum,0,sizeof(sum));
memset(tag,0,sizeof(tag));
memset(Set,0,sizeof(Set));
for (int i=1+M;i<=M*2+1;i++){//leaf
if(i<=n+M)scanf("%d",&sum[i]);
l[i] = r[i] = i-M ;
len[i]=1;
}
for (int t=M;t>=1;t--){//fathers
sum[t]=sum[lc]+sum[rc];
l[t]=l[lc], r[t]=r[rc];
len[t]=len[lc]+len[rc];
}
}
inline void down(int t){
if (t>M){Set[t]=tag[t]=0;return ;}//leaf node
if (Set[t]){
sum[lc]=Set[t]*len[lc];
sum[rc]=Set[t]*len[rc];
Set[lc]=Set[t];
Set[rc]=Set[t];
Set[t] = 0;
tag[lc]=tag[rc]=0;//!!!
}
if (tag[t]){
sum[lc]+=tag[t]*len[lc];
sum[rc]+=tag[t]*len[rc];
tag[lc]+=tag[t];
tag[rc]+=tag[t];
tag[t] = 0;
}
}
inline void _tag(int t,int x){
sum[t]+=x*len[t];
tag[t]+=x;
}
inline void _set(int t,int x){
sum[t]=x*len[t];
Set[t]=x;
tag[t]=0;//!!!
}
void change(int t,int L,int R,int x){
if (L<=l[t]&&r[t]<=R){_tag(t,x);return;}
down(t);
if (L<=mid)change(lc,L,R,x);
if (mid< R)change(rc,L,R,x);
sum[t]=sum[lc]+sum[rc];
}
void set(int t,int L,int R,int x){
if (L<=l[t]&&r[t]<=R){_set(t,x);return;}//in
down(t);
if (L<=mid)set(lc,L,R,x);
if (mid< R)set(rc,L,R,x);
sum[t]=sum[lc]+sum[rc];
}
int query(int t,int L,int R){
if (L<=l[t]&&r[t]<=R)return sum[t];
down(t);
int ans = 0;
if (L<=mid)ans+=query(lc,L,R);
if (mid< R)ans+=query(rc,L,R);
return ans;
}
}T;
int main(){
//freopen("fuck.in","r",stdin);
int ord,l,r,x;
for (;~scanf("%d%d",&n,&m);){
n++;
T.build(n);
for (;m--;){
scanf("%d%d%d%d",&ord,&l,&r,&x);
l++;r++;
if (ord) T.set(1,l,r,x);
else T.change(1,l,r,x);
printf("%d
",T.sum[1]);
}
}
return 0;
}
自己写的时候还是不够细心,down里面set直接复制的tag的
然后+=忘了改成=,同时忘了清空tag标记
以后写数据结构还是要细(la)心(ban)啊