*[作业]线段树合并练习
T1
真·板子
代码
#define N 5500000
#define M 110000
ll n,cnt,tot,x,y,ans[M],a[M],head[M];
ll RT[M],lc[N],rc[N],sum[N],as[N],val[N];
struct node{ll to,nxt;}e[M*2];
void add(ll f,ll to){e[++tot].to=to;e[tot].nxt=head[f];head[f]=tot;}
struct SMT{
#define LC lc[rt]
#define RC rc[rt]
#define _LC lc[_rt]
#define _RC rc[_rt]
#define GM ll mid=(l+r)>>1
void pushup(ll rt){
ll mnrt=sum[LC]>sum[RC]?LC:RC;
sum[rt]=sum[mnrt];val[rt]=val[mnrt];
if(sum[LC]==sum[RC])as[rt]=as[LC]+as[RC];
else as[rt]=as[mnrt];
}
void updata(ll &rt,ll l,ll r,ll a,ll v){
if(!rt)rt=++cnt;
if(l==r){sum[rt]+=v;val[rt]=l;as[rt]=l;return;}
GM;
if(a<=mid)updata(LC,l,mid,a,v);
else updata(RC,mid+1,r,a,v);
pushup(rt);
}
ll merge(ll rt,ll _rt,ll l,ll r){
if(!rt)return _rt;
if(!_rt)return rt;
if(l==r){sum[rt]+=sum[_rt];val[rt]=as[rt]=l;return rt;}
GM;
LC=merge(LC,_LC,l,mid);
RC=merge(RC,_RC,mid+1,r);
pushup(rt);
return rt;
}
}T;
void dfs(ll u,ll fa){
go(u)if(v!=fa)dfs(v,u),T.merge(RT[u],RT[v],1,n);//
T.updata(RT[u],1,n,a[u],1);ans[u]=as[RT[u]];
}
int main(){
n=read();rep(i,1,n)a[i]=read(),RT[i]=i,cnt++;rep(i,1,n-1)x=read(),y=read(),add(x,y),add(y,x);
dfs(1,0);
rep(i,1,n)writesp(ans[i]);
}
T2
发现封装后不太好调
加上个并查集就行了
代码
#define N 11000000
int n,m,q,x,y,tot,ans,cnt,head[N],f[N];
int RT[N],sum[N],val[N],lc[N],rc[N];
int getf(int x){return f[x]==x?x:f[x]=getf(f[x]);}
void mrg(int &x,int &y){x=getf(x),y=getf(y);if(x!=y)f[y]=x;}
//bool pd(int x,int y){x=getf(x);y=getf(y);return x==y;}
#define LC lc[rt]
#define RC rc[rt]
#define _LC lc[_rt]
#define _RC rc[_rt]
#define GM int mid=(l+r)>>1
void pushup(int rt){sum[rt]=sum[LC]+sum[RC];}
void updata(int &rt,int l,int r,int a,int v){
if(!rt)rt=++cnt;
if(l==r){val[rt]=v;sum[rt]++;return;}
GM;
if(a<=mid)updata(LC,l,mid,a,v);
else updata(RC,mid+1,r,a,v);
pushup(rt);
}
int merge(int rt,int _rt,int l,int r){
if(!rt)return _rt;if(!_rt)return rt;
if(l==r){if(val[_rt])val[rt]=val[_rt],sum[rt]+=sum[_rt];return rt;}
GM;
LC=merge(LC,_LC,l,mid);RC=merge(RC,_RC,mid+1,r);
pushup(rt);return rt;
}
int query(int rt,int l,int r,int k){
if(sum[rt]<k||!rt)return 0;
if(l==r)return val[rt];
GM;
if(k<=sum[LC])return query(LC,l,mid,k);
else return query(RC,mid+1,r,k-sum[LC]);
}
int main(){
n=read();m=read();rep(i,1,n)x=read(),updata(RT[i],1,n,x,i);
rep(i,1,n)f[i]=i;
rep(i,1,m)x=read(),y=read(),mrg(x,y),RT[x]=merge(RT[x],RT[y],1,n);q=read();char ch;
rep(i,1,q){
cin>>ch;x=read();y=read();
if(ch=='Q')x=getf(x),ans=query(RT[x],1,n,y),writeln(ans);
else if(ch=='B'){
mrg(x,y);if(x!=y)RT[x]=merge(RT[x],RT[y],1,n);
}
}
}
T3
dfs可能有点怪。。。
代码
#define N 220000
#define M 44000000
#define GM ll mid=(l+r)>>1
#define LC lc[rt]
#define RC rc[rt]
#define _LC lc[_rt]
#define _RC rc[_rt]
ll n,ans1,ans2,ans,cnt,lc[M],rc[M],sum[M];
//void pushup(ll rt){sum[rt]=sum[LC]+sum[RC];}
void updata(ll &rt,ll l,ll r,ll k){
if(!rt)rt=++cnt;sum[rt]++;if(l==r)return;
GM;if(k<=mid)updata(LC,l,mid,k);else updata(RC,mid+1,r,k);
}
void merge(ll &rt,ll _rt){
if(!rt||!_rt){rt=rt+_rt;return;}sum[rt]+=sum[_rt];
ans1+=sum[RC]*sum[_LC];ans2+=sum[LC]*sum[_RC];
merge(LC,_LC);merge(RC,_RC);
}
ll dfs(){
ll lc=0,rc=0,v,u=0;
v=read();
if(!v){
lc=dfs();rc=dfs();
ans1=0,ans2=0;
u=lc,merge(u,rc);
ans+=min(ans1,ans2);
}
else updata(u,1,n,v);
return u;
}
int main(){n=read();dfs();write(ans);}
T4
代码
我咕咕咕

浙公网安备 33010602011771号