线段树这两种写法有什么区别?
查看原帖
线段树这两种写法有什么区别?
484894
_Archive_楼主2023/8/9 17:49

第一种改成第二种A了这是为什么。

第一种就是建树的时候记录左右编号,后面直接用,结果全RE无法运行。(问题应该出现在线段树的板子)

有无大佬解释一下。

话说哪种写法比较好。

#include<bits/stdc++.h>
#define db double
#define lb long double
#define pf(x) cout<<(x)<<endl;
#define int long long
//#pragma GCC optimize(2)
using namespace std;
inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
const int N = 1e5+10;
struct E{
	int to,nxt;
}e[N<<2];
struct node{
    int l,r,L,R,cnt,tag;
}t[N<<2];
int n,m,w[N],fa[N],son[N],dfn[N],tim,sz[N],dep[N],top[N];
int a[N],cnt,head[N];
void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
struct Tree{
	#define ls p<<1
	#define rs p<<1|1
	node mg(node x,node y){
    	node r;
    	r.tag=0;
    	r.l=x.l;
    	r.r=y.r;
    	r.cnt=x.cnt+y.cnt;
    	if (x.r==y.l) r.cnt--;
    	return r;
	}
	void upd(int p) {
    	t[p]=mg(t[ls],t[rs]);
	}
	void mvtag(int p,int k){
    	t[p].cnt=1;
    	t[p].l=t[p].r=k;
    	t[p].tag=k;
	}
	void psd(int p){
    	if(t[p].tag){
        	mvtag(ls,t[p].tag);
        	mvtag(rs,t[p].tag);
        	t[p].tag=0;
    	}
	}
	void build(int p,int l,int r){
		t[p].L=l;
		t[p].R=r;
		t[p].tag=0;
		if(l==r){
			t[p].l=t[p].r=a[l];
			t[p].cnt=1;
			return;
		}
		int mid=(l+r)>>1;
		build(ls,l,mid);
		build(rs,mid+1,r);
		upd(p);
	}
	void cg(int p,int l,int r,int k){
    	if(l<=t[p].L&&t[p].R<=r){
       	 	t[p].tag=k;
        	t[p].l=t[p].r=k;
        	t[p].cnt=1;
        	return;
    	}
    	psd(p);
    	int mid=(t[p].L+t[p].R)>>1;
    	if(l<=mid)cg(ls,l,r,k);
    	if(r>mid)cg(rs,l,r,k);
    	upd(p);
	}	
	node query(int p,int l,int r) {
    	if(l<=t[p].L&&t[p].R<=r) return t[p];
    	psd(p);
    	int mid=(t[p].L+t[p].R)>>1;
    	bool f=0;
    	node ans;
    	if(l<=mid){
        	f=1;
        	ans=query(ls,l,r);
    	}
    	if(mid<r){
        	if(f) ans=mg(ans,query(rs,l,r));
			else ans=query(rs,l,r);
    	}
    	return ans;
	}
}T;
void add(int u,int v,int c){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		T.cg(1,dfn[top[u]],dfn[u],c);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v);
	T.cg(1,dfn[v],dfn[u],c);
}
int query(int u,int v){
	int r=0;
	node lstu,lstv,nowu,nowv;
	lstu.cnt=lstu.l=lstu.r=lstu.tag=0;
	lstv.cnt=lstv.l=lstv.r=lstv.tag=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]){
			nowv=T.query(1,dfn[top[v]],dfn[v]);
			r+=nowv.cnt;
			if(nowv.r==lstv.l) r--;
			lstv=nowv;
			v=fa[top[v]];
		}
		else{
			nowu=T.query(1,dfn[top[u]],dfn[u]);
			r+=nowu.cnt;
			if(nowu.r==lstu.l) r--;
			lstu=nowu;
			u=fa[top[u]];
		}
	}
	if(dep[u]<dep[v]){
		nowv=T.query(1,dfn[u],dfn[v]);
		r+=nowv.cnt;
		if(nowv.r==lstv.l) r--;
		lstv=nowv;
	}
	else{
		nowu=T.query(1,dfn[v],dfn[u]);
		r+=nowu.cnt;
		if(nowu.r==lstu.l) r--;
		lstu=nowu;
	}
	if(lstu.l==lstv.l&&lstu.r!=0) r--;
	return r;
}
int dfs1(int x,int f){
	fa[x]=f;
	dep[x]=dep[f]+1;
	sz[x]=1;
	for(int i=head[x];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==f) continue;
		sz[x]+=dfs1(v,x);
		if(sz[v]>sz[son[x]]) son[x]=v;
	}
	return sz[x];
}
void dfs2(int x,int tp){
	dfn[x]=++tim;
	a[tim]=w[x];
	top[x]=tp;
	if(!son[x]) return;
	dfs2(son[x],tp);
	for(int i=head[x];i;i=e[i].nxt){
		int v=e[i].to;
		if(dfn[v]) continue;
		dfs2(v,v);
	}
}
signed main() {
    n=read(),m=read();
    for (int i=1;i<=n;++i)w[i]=read();
    for (int i=1;i<n;++i) {
        int u=read(),v=read();
        add(u,v);
        add(v,u);
    }
    dfs1(1,0);
    dfs2(1,1);
    T.build(1,1,n);
    for (int i=1;i<=m;++i) {
        char op;
        scanf("%s",&op);
        if(op=='C'){
            int a=read(),b=read(),c=read();
            add(a,b,c);
        } 
		else{
            int a=read(),b=read();
            printf("%lld\n",query(a,b));
        }
    }
    return 0;
}
#include<bits/stdc++.h>
#define db double
#define lb long double
#define pf(x) cout<<(x)<<endl;
#define int long long
//#pragma GCC optimize(2)
using namespace std;
inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
const int N = 1e5+10;
struct E{
	int to,nxt;
}e[N<<2];
struct node{
    int l,r,L,R,cnt,tag;
}t[N<<2];
int n,m,w[N],fa[N],son[N],dfn[N],tim,sz[N],dep[N],top[N];
int a[N],cnt,head[N];
void add(int u,int v){
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
struct Tree{
	#define ls p<<1
	#define rs p<<1|1
	node mg(node x,node y){
    	node r;
    	r.tag=0;
    	r.l=x.l;
    	r.r=y.r;
    	r.cnt=x.cnt+y.cnt;
    	if (x.r==y.l) r.cnt--;
    	return r;
	}
	void upd(int p) {
    	t[p]=mg(t[ls],t[rs]);
	}
	void mvtag(int p,int k){
    	t[p].cnt=1;
    	t[p].l=t[p].r=k;
    	t[p].tag=k;
	}
	void psd(int p){
    	if(t[p].tag){
        	mvtag(ls,t[p].tag);
        	mvtag(rs,t[p].tag);
        	t[p].tag=0;
    	}
	}
	void build(int p,int l,int r){
		t[p].L=l;
		t[p].R=r;
		t[p].tag=0;
		if(l==r){
			t[p].l=t[p].r=a[l];
			t[p].cnt=1;
			return;
		}
		int mid=(l+r)>>1;
		build(ls,l,mid);
		build(rs,mid+1,r);
		upd(p);
	}
	void cg(int p,int L,int R,int l,int r,int k){
    	if(l<=L&&R<=r){
       	 	t[p].tag=k;
        	t[p].l=t[p].r=k;
        	t[p].cnt=1;
        	return;
    	}
    	psd(p);
    	int mid=(L+R)>>1;
    	if(l<=mid)cg(ls,L,mid,l,r,k);
    	if(r>mid)cg(rs,mid+1,R,l,r,k);
    	upd(p);
	}	
	node query(int p,int L,int R,int l,int r) {
    	if(l<=L&&R<=r) return t[p];
    	psd(p);
    	int mid=(L+R)>>1;
    	bool f=0;
    	node ans;
    	if(l<=mid){
        	f=1;
        	ans=query(ls,L,mid,l,r);
    	}
    	if(mid<r){
        	if(f) ans=mg(ans,query(rs,mid+1,R,l,r));
			else ans=query(rs,mid+1,R,l,r);
    	}
    	return ans;
	}
}T;
void add(int u,int v,int c){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		T.cg(1,1,n,dfn[top[u]],dfn[u],c);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v);
	T.cg(1,1,n,dfn[v],dfn[u],c);
}
int query(int u,int v){
	int r=0;
	node lstu,lstv,nowu,nowv;
	lstu.cnt=lstu.l=lstu.r=lstu.tag=0;
	lstv.cnt=lstv.l=lstv.r=lstv.tag=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]){
			nowv=T.query(1,1,n,dfn[top[v]],dfn[v]);
			r+=nowv.cnt;
			if(nowv.r==lstv.l) r--;
			lstv=nowv;
			v=fa[top[v]];
		}
		else{
			nowu=T.query(1,1,n,dfn[top[u]],dfn[u]);
			r+=nowu.cnt;
			if(nowu.r==lstu.l) r--;
			lstu=nowu;
			u=fa[top[u]];
		}
	}
	if(dep[u]<dep[v]){
		nowv=T.query(1,1,n,dfn[u],dfn[v]);
		r+=nowv.cnt;
		if(nowv.r==lstv.l) r--;
		lstv=nowv;
	}
	else{
		nowu=T.query(1,1,n,dfn[v],dfn[u]);
		r+=nowu.cnt;
		if(nowu.r==lstu.l) r--;
		lstu=nowu;
	}
	if(lstu.l==lstv.l&&lstu.r!=0) r--;
	return r;
}
int dfs1(int x,int f){
	fa[x]=f;
	dep[x]=dep[f]+1;
	sz[x]=1;
	for(int i=head[x];i;i=e[i].nxt){
		int v=e[i].to;
		if(v==f) continue;
		sz[x]+=dfs1(v,x);
		if(sz[v]>sz[son[x]]) son[x]=v;
	}
	return sz[x];
}
void dfs2(int x,int tp){
	dfn[x]=++tim;
	a[tim]=w[x];
	top[x]=tp;
	if(!son[x]) return;
	dfs2(son[x],tp);
	for(int i=head[x];i;i=e[i].nxt){
		int v=e[i].to;
		if(dfn[v]) continue;
		dfs2(v,v);
	}
}
signed main() {
    n=read(),m=read();
    for (int i=1;i<=n;++i)w[i]=read();
    for (int i=1;i<n;++i) {
        int u=read(),v=read();
        add(u,v);
        add(v,u);
    }
    dfs1(1,0);
    dfs2(1,1);
    T.build(1,1,n);
    for (int i=1;i<=m;++i) {
        char op;
        scanf("%s",&op);
        if(op=='C'){
            int a=read(),b=read(),c=read();
            add(a,b,c);
        } 
		else{
            int a=read(),b=read();
            printf("%lld\n",query(a,b));
        }
    }
    return 0;
}
2023/8/9 17:49
加载中...