求助卡常
查看原帖
求助卡常
383791
Others楼主2023/11/16 20:02

复杂度应该是对的,如果你知道我哪里常数可以大优化(不管需要多么复杂的重构),你都可以提出来。

#include <bits/stdc++.h>
#define ll long long
#define uint unsigned int
#define wr(x,ch) write(x),putchar(ch)
#define pcnt(x) __builtin_popcount(x)
#define plst(x) __builtin_ctz(x)
using namespace std;
int Tim=0;
namespace IO{//by cyffff
	int len=0;
	#define gh() getchar()
	inline int read(){
		char ch=gh();
		int x=0;
		char t=0;
		while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();
		while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();
		return t?-x:x;
	}
	template<class T>inline void write(T x){
		if(x<0)putchar('-'),x=-x;
		if(x>9)write(x/10);
		putchar(x%10^48);
	}
}
using IO::read;
using IO::write;
const uint N=100005,TMP1=(1u<<5)-1,TMP2=-1;
int a[N],A[N],Ans[N],ans,aans,n,m,x,u,v,s,L[N],R[N],idx[N],rt[N],rt2[N],fa1[N],fa2[N],flag[N],pl,pr,l,r;
ll tim;
int bls;
struct query {
	int l,r,id;
	bool operator<(const query &p) const {
		return idx[l]==idx[p.l]?r<p.r:l<p.l;
	}
}p[N];
vector<int> G[N],vec;
struct Canc {
	int x,y;
}canc[N];int ccnt;
struct node1 {
	uint ch[10],op,s;
}tr[N];int cnt1;
struct node2 {
	uint c[32],op,s;
}tr2[N*2];int sta[N],top,cnt2;
int new1() { 
	++cnt1;
	tr[cnt1].s=0;
	int t=0;
	while(tr[cnt1].op) {
		tim++;
		t=plst(tr[cnt1].op);
		tr[cnt1].ch[t]=0;
		tr[cnt1].op^=(1u<<t);
	}
	return cnt1;
}
int new2() {
	int t,T;
	if(top) t=sta[top--];
	else t=++cnt2;
	while(tr2[t].op) {
		tim++;
		T=plst(tr2[t].op);
		tr2[t].c[T]=0;
		tr2[t].op^=(1u<<T);
	}
	tr2[t].s=0;
	return t;
}
void ins(int p,int x) {
	int t=tr[p].ch[x>>10]=new2();
	tr[p].op|=(1u<<(x>>10));
	tr2[t].op|=(1u<<(x>>5&TMP1));
	tr2[t].c[x>>5&TMP1]|=(1u<<(x&TMP1));
	tr[p].s=tr2[t].s=1;
	return ;
}
int get(int x,int *fa) {
	return x==fa[x]?x:fa[x]=get(fa[x],fa);
}
void merge(int p,int q,int o) {
	int t=tr[p].op&tr[q].op,t2=tr[q].op^t,t3,t4,t5,t6,t7,t8;
	tr[p].op|=t2;
	while(t2) {
		tim++;
		t3=plst(t2);
		if(o) t4=new2(),tr2[t4]=tr2[tr[q].ch[t3]];
		else t4=tr[q].ch[t3];
		tr[p].ch[t3]=t4;
		tr[p].s+=tr2[t4].s;
		t2^=(1u<<t3);
	}
	while(t) {
		tim++;
		t3=plst(t);
		t4=tr[p].ch[t3],t5=tr[q].ch[t3];
		tr[p].s-=tr2[t4].s;
		tr2[t4].s+=tr2[t5].s;
		t6=tr2[t4].op&tr2[t5].op,t7=tr2[t5].op^t6;
		t^=(1u<<t3);
		while(t7) {
			tim++;
			t8=plst(t7);
			tr2[t4].op|=(1u<<t8);
			tr2[t4].c[t8]=tr2[t5].c[t8];
			t7^=(1u<<t8);
		}
		while(t6) {
			tim++;
			t8=plst(t6);
			tr2[t4].s-=(pcnt(tr2[t4].c[t8]&tr2[t5].c[t8])<<1);
			tr2[t4].c[t8]^=tr2[t5].c[t8];
			if(!tr2[t4].c[t8]) tr2[t4].op&=((TMP2)^(1u<<t8));
			t6^=(1u<<t8);
		}
		if(tr2[t4].s) tr[p].s+=tr2[t4].s;
		else tr[p].op&=((TMP2)^(1u<<t3)),tr[p].ch[t3]=0,sta[++top]=t4;
	}
	return ;
} 
int main() {
// 	freopen("data.in","r",stdin);
// 	freopen("data.out","w",stdout);
	n=read(),m=read(),x=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<n;i++) u=read(),v=read(),G[u].push_back(v),G[v].push_back(u);
	for(int i=0;i<=x;i++) A[i]=read();
	s=n*log2(n)/sqrt(m)+1;
	for(int i=1;i<=n;i++) fa1[i]=i;
	for(int i=1;i<=n;i++) rt[i]=new1(),ins(rt[i],a[i]);
	for(int i=n;i>=1;i--) {
		int j=i;
		tim=0;
		flag[i]=1;
		int t1;
		for(const auto &lxl:G[i]) {
			if(flag[lxl]) {
				t1=get(lxl,fa1);
				if(tr[rt[i]].s>tr[rt[t1]].s) swap(rt[i],rt[t1]);
				fa1[t1]=i;
				merge(rt[i],rt[t1],0);
			}
		}
		while(j>1) {
			j--;
			flag[j]=1;
			for(const auto &lxl:G[j]) {
				if(flag[lxl]) {
					t1=get(lxl,fa1);
					if(tr[rt[j]].s>tr[rt[t1]].s) swap(rt[j],rt[t1]);
					fa1[t1]=j;
					merge(rt[j],rt[t1],0);
				}
			}
			if(tim>s) break;
		}
		if(tim>s) j++;
		bls++;
		for(int k=j;k<=i;k++) idx[k]=bls;
		L[bls]=j,R[bls]=i;
		i=j;
	}
	for(int i=1;i<=n;i++) idx[i]=bls-idx[i]+1;
	for(int i=1;i<=bls;i++) 
		if(i<bls-i+1) swap(L[i],L[bls-i+1]),swap(R[i],R[bls-i+1]);
	for(int i=1;i<=m;i++) p[i].l=read(),p[i].r=read(),p[i].id=i;
	sort(p+1,p+m+1);
	for(int now=-1,z=1;z<=m;z++) {
		pl=p[z].l,pr=p[z].r;
		if(idx[pl]==idx[pr]) {
			cnt1=cnt2=top=ans=0;
			for(int i=pl;i<=pr;i++) {
				fa1[i]=i;
				rt[i]=new1(),ins(rt[i],a[i]),ans+=A[1];
				int t1;
				for(const auto &lxl:G[i]) 
					if(pl<=lxl&&lxl<=i) {
						t1=get(lxl,fa1);
						if(tr[rt[i]].s>tr[rt[t1]].s) 
							swap(rt[i],rt[t1]);
						fa1[t1]=i;
						ans-=A[tr[rt[i]].s],ans-=A[tr[rt[t1]].s];
						merge(rt[i],rt[t1],0);
						ans+=A[tr[rt[i]].s];
					}
			}
			Ans[p[z].id]=ans;
			continue;
		}
		if(now!=idx[pl]) {
			now=idx[pl];
			l=R[now],r=l-1;
			ans=cnt1=cnt2=top=0;
			memset(flag,0,sizeof(flag));
			for(int i=1;i<=n;i++) fa1[i]=i,rt[i]=new1(),ins(rt[i],a[i]);
		} 
		int t1;
		while(r<pr) {
			++r;
			flag[r]=1;
			fa1[r]=r;
			ans+=A[1];
			for(const auto &lxl:G[r]) 
				if(flag[lxl]) {
					t1=get(lxl,fa1);
					if(tr[rt[r]].s>tr[rt[t1]].s) swap(rt[r],rt[t1]);
					fa1[t1]=r;
					ans-=A[tr[rt[r]].s],ans-=A[tr[rt[t1]].s];
					merge(rt[r],rt[t1],0);
					ans+=A[tr[rt[r]].s];
				}
		}
		aans=ans;vec.clear();
		for(int i=l-1;i>=pl;i--) {
			fa2[i]=i,aans+=A[1];
			flag[i]=1;
			vec.push_back(i);
			for(const auto &lxl:G[i]) 
				if(flag[lxl]) {
					t1=get(lxl,fa1);
					if(fa2[t1]) fa2[get(t1,fa2)]=i;
					else fa2[t1]=i,vec.push_back(t1);
				}
		}
		for(const auto &lxl:vec) aans-=A[tr[rt[lxl]].s],rt2[lxl]=rt[lxl];
		for(const auto &lxl:vec) {
			t1=get(lxl,fa2);
			if(t1!=lxl) {
				tim++;
				if(tr[rt2[t1]].s>tr[rt2[lxl]].s) swap(rt2[t1],rt2[lxl]);
				canc[++ccnt]=(Canc){rt2[t1],rt2[lxl]};
				merge(rt2[t1],rt2[lxl],1);
			}
		}
		for(const auto &lxl:vec) {
			if(fa2[lxl]==lxl) aans+=A[tr[rt2[lxl]].s];
			fa2[lxl]=0;
		}
		Ans[p[z].id]=aans;
		while(ccnt) merge(canc[ccnt].x,canc[ccnt].y,1),ccnt--;
		for(int i=pl;i<l;i++) flag[i]=0;
	}
	for(int i=1;i<=m;i++) printf("%d\n",Ans[i]);
	return 0;
}
2023/11/16 20:02
加载中...