全RE(爆栈求助)
查看原帖
全RE(爆栈求助)
1039406
mayike楼主2023/12/29 02:06
//想知道为什么会爆栈,且输入都没输入完,求助!
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,T,qcnt,acnt,vol[N],w[N],c[N],p[20][N],bl[N],stk[N],d[N],num[N],top,blo,tot,sj;
long long Ans,ans[N];bool vis[N];
inline void swap(int &aa,int &bb){
	aa^=bb;
	bb^=aa;
	aa^=bb;
}
inline void read(int &x){
    x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9'){
        x=(x<<3)+(x<<1)+(ch^48);
        ch=getchar();
    }
}
void print(long long x){
    if(x>9)print(x/10);
    putchar(x%10+'0');
}
struct qxx{
	int v,nxt;
}e[N<<2];
int cnt,h[N];
void sbm(int x,int y){
	e[++cnt]={y,h[x]},h[x]=cnt;
}
struct sb{
	int u,v,t,id;
	bool operator<(const sb & b)const {
	    return bl[u]==bl[b.u]?(bl[v]==bl[b.v]?t<b.t:bl[v]<bl[b.v]):bl[u]<bl[b.u];
	}//重载运算符跑得更快 
}q[N];
struct ssb{
	int p,col;
}a[N];
void dsb(int u){
	int t=top;
	for(int i=h[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==p[u][0])continue;
		p[v][0]=u;
		d[v]=d[u]+1;
		dsb(v);
		if(top-t>=blo){
			tot++;
		    while(top>t)bl[stk[top--]]=tot;
	    }
	}stk[++top]=u;
}
int lca(int u,int v){
	if(d[u]<d[v])swap(u,v);
	int i;
	for(i=17;i>=0;i--)if(d[u]-(1<<i)>=d[v])u=p[u][i];
	if(u==v)return v;
	for(i=17;i>=0;i--)if(p[u][i]!=-1&&p[u][i]!=p[v][i])u=p[u][i],v=p[v][i];
	return p[u][0];
}
void add(int x){
	if(vis[x])Ans-=1ll*vol[c[x]]*w[num[c[x]]--];
	else Ans+=1ll*vol[c[x]]*w[++num[c[x]]];
	vis[x]^=1; 
}
void wdf(int u,int v){//小型LCA 
	if(d[u]<d[v])swap(u,v);
	while(d[u]>d[v]){
		add(u);
		u=p[u][0];
	}while(u!=v){//对于加值,一条线往返和是相同的,故不影响 
		add(u),add(v);
		u=p[u][0],v=p[v][0];
	}//若这里放add(u)是错误的,因为是一棵树,u此时为原始的lc0=lca(u0,v0),作图可知 lc0 要么在u~v路径上,要么不在(故不影响 
}
void cnm(int tj){
	if(vis[a[tj].p]){//被走过一次(非lca) 
		add(a[tj].p);
		swap(c[a[tj].p],a[tj].col);
		add(a[tj].p);
	}else swap(c[a[tj].p],a[tj].col);//没被走过 or lca 
}
int main(){
	int i,j,u,v,tye,ab;
	read(n),read(m),read(T);
	blo=pow(n,2.0/3);
	for(i=1;i<=m;i++)read(vol[i]);
	for(i=1;i<=n;i++)read(w[i]);
	for(i=1;i<n;i++){
		read(u),read(v);
		sbm(u,v),sbm(v,u);
	}memset(p,-1,sizeof p);
	dsb(1);
	for(j=1;j<=17;j++)
	    for(i=1;i<=n;i++)if(p[i][j-1]!=-1)p[i][j]=p[p[i][j-1]][j-1];
	while(top)bl[stk[top--]]=tot;
	for(i=1;i<=n;i++)read(c[i]);
	for(i=1;i<=T;i++){
		read(tye),read(u),read(v);
		if(tye)qcnt++,q[qcnt]={u,v,acnt,qcnt};
		else acnt++,a[acnt]={u,v};
	}sort(q+1,q+1+qcnt);//直接排序 
	u=v=1;//1为起始点
	for(i=1;i<=qcnt;i++){
		wdf(u,q[i].u);
		wdf(v,q[i].v);
		u=q[i].u,v=q[i].v;
		while(sj<q[i].t)cnm(++sj);
		while(sj>q[i].t)cnm(sj--);
		ab=lca(u,v);
		add(ab);//加了 
		ans[q[i].id]=Ans;//赋值
		add(ab);//删掉
	}for(i=1;i<=qcnt;i++)print(ans[i]),putchar('\n');
	return 0;
}//板子题---莫队---树上带修莫队---e訫,庸俗,老套---也就花了我三夜时间而已 
2023/12/29 02:06
加载中...