一个简单的线段树
支持把某个区间内的点都改为z,求所有操作之后的区间和
#include<bits/stdc++.h>
using namespace std;
const int maxn = 112345;
int arr[maxn * 4];
int lazy[maxn * 4];
#define root 1,1,n
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define Now int o,int l,int r
#define Mid int m = (l+r)/2
void push_down(int o,int l,int r){
if(l == r){
lazy[o] = 0;
return;
}
Mid;
int v = lazy[o];
lazy[o] = 0;
arr[o<<1] = v * (m - l + 1);
arr[o<<1|1] = v * (r - m);
lazy[o<<1] = lazy[o<<1|1] = v;
}
void update(Now,int ul,int ur,int v){
if(ul <= l && r <= ur){
arr[o] = ( r - l + 1) * v;
lazy[o] = v;
return;
}
Mid;
if(lazy[o]){
push_down(o,l,r);
}
if(ul <= m) update(lson,ul,ur,v);
if(m+1 <= ur) update(rson,ul,ur,v);
arr[o] = arr[o<<1] + arr[o<<1|1];
}
int main(){
int T;
scanf("%d",&T);
int n,m;
int icase = 1;
while(T-- && ~scanf("%d %d",&n,&m)){
update(root,1,n,1);
int l,r,v;
while(m--){
scanf("%d %d %d",&l,&r,&v);
update(root,l,r,v);
}
printf("Case %d: The total value of the hook is %d.\n",icase++,arr[1]);
}
return 0;
}
我怎么这么熟练啊(╯‵□′)╯︵┻━┻
用splay强行写了一发。。
#include<bits/stdc++.h>
using namespace std;
struct Info{
int sum;
int size;
Info(int m = 0){
sum = m;
size = 1;
}
void upd(int x){
sum = size * x;
}
};
Info operator + (const Info & L,const Info & R){
Info ret(L.sum+R.sum);
ret.size = L.size + R.size;
return ret;
}
const int maxn = 112345;
struct Node{
int son[2],fa;
int v,lazy;
Info info;
int & l(){return son[0];}
int & r(){return son[1];}
Node(int V=0){
l() = r() = fa = -1;
v = V;
info = Info(v);
lazy = -1;
}
void upd(int V){
v = V;
lazy = V;
info.upd(V);
}
void maintain();
void push_down();
}node[maxn];
void Node::push_down(){
if(lazy != -1){
if(l()!=-1) node[l()].upd(lazy);
if(r()!=-1) node[r()].upd(lazy);
lazy = -1;
}
}
void Node::maintain(){
info = Info(v);
if(l()!=-1) info = node[l()].info + info;
if(r()!=-1) info = info + node[r()].info;
}
int ori(int st){
int fa = node[st].fa;
if(fa==-1) return -1;
//printf("st %d fa %d fa.r %d equ %d\n",st,fa,node[fa].r(),st == node[fa].r());
return st == node[fa].r();
}
void setc(int st,int sn,int d){
if(st != -1){
node[st].son[d] = sn;
node[st].maintain();
}
if(sn != -1) node[sn].fa = st;
}
void zg(int x){
int st = node[x].fa,p = -1;
node[st].push_down();
node[x].push_down();
int d = ori(x),dst = ori(st);
if(st!=-1) p=node[st].fa;
setc(st,node[x].son[d^1],d);
setc(x,st,d^1);
setc(p,x,dst);
}
void splay(int x,int fa=-1){
auto f = [=](int x){return node[x].fa;};
while(f(x) != fa){
// printf("fx = %d\n",f(x));
if(f(f(x)) == fa) zg(x);
else{
if(ori(x)==ori(f(x))) zg(f(x));
else zg(x);
zg(x);
}
}
}
int ider[maxn];
int pos;
int build(int l,int r){
int st = pos++;
int m = (l + r) >> 1;
node[st] = Node(1);
ider[m] = st;
if(l<m) setc(st,build(l,m-1),0);
if(m<r) setc(st,build(m+1,r),1);
return st;
}
int build(int n){
pos = 0;
return build(0,n+1);
}
int getseg(int l,int r){
l = ider[l-1],r = ider[r+1];
splay(r);
splay(l,r);
return node[l].r();
}
void update(int l,int r,int v){
node[getseg(l,r)].upd(v);
}
int query(int n){
return node[getseg(1,n)].info.sum;
}
int main(){
int T;
scanf("%d",&T);
int icase = 1;
int n,m;
while(T-- && ~scanf("%d %d",&n,&m)){
build(n);
int l,r,v;
while(m--){
scanf("%d %d %d",&l,&r,&v);
if(l > r) swap(l,r);
update(l,r,v);
}
printf("Case %d: The total value of the hook is %d.\n",icase++,query(n));
}
return 0;
}