蒟蒻刚学莫队,求助!!!第7个点疯狂TLE
查看原帖
蒟蒻刚学莫队,求助!!!第7个点疯狂TLE
247695
AuroraKelsey楼主2020/10/9 10:24

#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;
const int N=200005;
#define re register
inline int read() {
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x;
}
template<typename F>
inline void write(F x, char ed = '\n')
{
	static short st[30];short tp=0;
	if(x<0) putchar('-'),x=-x;
	do st[++tp]=x%10,x/=10; while(x);
	while(tp) putchar('0'|st[tp--]);
	putchar(ed);
}
int n,m,Q;
ll v[N],w[N],c[N],cnt[N];
int bel[N];
struct modui{
	int l,r,tim,lca,id;
	bool operator < (const modui &x) const {
		return (bel[l]^bel[x.l])?bel[l]<bel[x.l]:(bel[r]^bel[x.r])?bel[r]<bel[x.r]:tim<x.tim;
	}
}q[N];
struct CH{
	int pos;ll val;
}g[N];
int hd[N],to[N<<1],nxt[N<<1],tot;
inline void add(int x,int y) {
	to[++tot]=y;nxt[tot]=hd[x];hd[x]=tot;
	to[++tot]=x;nxt[tot]=hd[y];hd[y]=tot;
}

int dep[N],dfn_in[N],dfn_out[N],rev[N],dfn_cnt;
int euler[N],dfn[N],len;
inline void dfs(int x,int fa,int d) {
	dep[x]=d;
	dfn[x]=++len;euler[len]=x;
	dfn_in[x]=++dfn_cnt;rev[dfn_cnt]=x;
	for(re int i=hd[x];i;i=nxt[i])
		if(to[i]!=fa) {
			dfs(to[i],x,d+1);
			euler[++len]=x;
		} 
	dfn_out[x]=++dfn_cnt;rev[dfn_cnt]=x;
}
int st[20][N],lg[N];
inline int Min(int x,int y) {
	return dep[x]<dep[y]?x:y;
}
inline int LCA(int x,int y) {
	int le=dfn[x]<dfn[y]?dfn[x]:dfn[y],ri=dfn[x]>dfn[y]?dfn[x]:dfn[y];
	int k=lg[ri-le+1];
	return Min(st[k][le],st[k][ri-(1<<k)+1]);
}
ll res;
inline void add(int pos) {res+=1ll*v[c[pos]]*w[++cnt[c[pos]]];}
inline void del(int pos) {res-=1ll*v[c[pos]]*w[cnt[c[pos]]--];}
bool vis[N];
inline void work(int pos) {
	vis[pos]?del(pos):add(pos);
	vis[pos]^=1;
}
inline void change(int x,int i) {
	if(vis[g[x].pos]) {
		work(g[x].pos);
		swap(c[g[x].pos],g[x].val);
		work(g[x].pos);
	} 
	if(!vis[g[x].pos])
		swap(c[g[x].pos],g[x].val);
}
int qm,cm,now,size;
ll ans[N];

int main() {
	n=read();m=read();Q=read();
	size=pow(n,2.0/3.0);
	for(re int i=1;i<=m;i++) v[i]=read();
	for(re int i=1;i<=n;i++) w[i]=read();
	for(re int i=2;i<=n;i++) 
		add(read(),read());
	for(re int i=1;i<=n;i++) 
		c[i]=read(),bel[i]=(i-1)/size+1;;
	dfs(1,0,1);
	lg[0]=-1;
	for(int i=1;i<=len;i++) lg[i]=lg[i>>1]+1;
	for(int i=1;i<=len;i++) st[0][i]=euler[i];
	for(int j=1;(1<<j)<=len;j++)
		for(int i=1;i+(1<<j)-1<=len;i++)
			st[j][i]=Min(st[j-1][i],st[j-1][i+(1<<(j-1))]);
	
	for(re int i=1,ty,a,b;i<=Q;i++) {
		ty=read();a=read();b=read();
		if(ty) {
			int lca=LCA(a,b);
			if(dfn_in[a]>dfn_in[b]) swap(a,b);
			a==lca?( q[++qm].l=dfn_in[a],q[qm].r=dfn_in[b]):(q[++qm].l=dfn_out[a],q[qm].r=dfn_in[b],q[qm].lca=lca);
			q[qm].tim=cm;q[qm].id=qm;
		} 
		if(!ty) 
			g[++cm].pos=a,g[cm].val=b;
	}
	sort(q+1,q+1+qm);
	int l=1,r=0;
	for(re int i=1;i<=qm;i++) {
		int nowl=q[i].l,nowr=q[i].r;
		while(r<nowr) work(rev[++r]); 
		while(l>nowl) work(rev[--l]); 
		while(l<nowl) work(rev[l++]);
		while(r>nowr) work(rev[r--]);
		while(now<q[i].tim) change(++now,i);
		while(now>q[i].tim) change(now--,i);
		if(q[i].lca) work(q[i].lca);
		ans[q[i].id]=res;
		if(q[i].lca) work(q[i].lca);
	}
	for(re int i=1;i<=qm;i++)
		write(ans[i]);
	return 0;
}
2020/10/9 10:24
加载中...