想说的是调代码的问题啦。

我调了一个上午+一个下午原因竟然是因为排序以为(x,y,t)不同,两个操作就不同了,本身大部分情况是这样的。但是自己先前给自己挖了坑,我把一开始默认的边的时间戳设的1,跟第一个操作的时间戳相同。然后我就gg了(因为只要第一个是2操作,还要加上按修改在删除前)。我也很无语,不过真的很难想到这个问题,加上一直以为自己的线段树分治里面写错了。而且调大数据的时候一定要慢,不要急,要想清楚每一步要做的什么了,慢慢分析清楚了,再下一步。

  • code:
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
typedef long long ll;
int ans[N],n,m,q,up=30,Bs[31];
struct query {int opt,x,y,z,t;}s[N];
struct seg {int l,r;}T[N<<1];
struct node {int x,y;};
vector<node>Q[N<<1];
vector<int>V[N<<1];
bool cmp(query u,query v) {return u.x^v.x?u.x<v.x:(u.y^v.y?u.y<v.y:(u.t^v.t?u.t<v.t:u.opt<v.opt));}
void Build(int x,int l,int r) {
	T[x]=(seg){l,r};
	if(l==r)return;
	int mid=(l+r)>>1;
	Build(x<<1,l,mid),Build(x<<1|1,mid+1,r);
}
void Update(int x,int l,int r,int p) {
	if(l<=T[x].l&&T[x].r<=r) {V[x].push_back(p);return;}
	int mid=(T[x].l+T[x].r)>>1;
	if(l<=mid) Update(x<<1,l,r,p);
	if(r>mid) Update(x<<1|1,l,r,p);
}
bool flag=0;
void Insert(int y) {
	for(int i=up;y&&i>=0;i--) {
		if((y>>i)&1) {
			if(!Bs[i]){Bs[i]=y;return;}
			else y^=Bs[i];
		}
	}
}
int Mn(int y) {
	for(int i=up;i>=0;i--) {
		if((y>>i)&1) {
			y^=Bs[i];
		}
	}
	return y;
}
int st[N],tp,sz[N],fa[N],xos[N],we[N];
int g_fa(int x) {
	if(fa[x]==x)return x;
	int f=fa[x],fx=g_fa(f);
	xos[x]=xos[f]^we[x];
	return fx;
}
bool Union(int p) {
	int x=s[p].x,y=s[p].y,z=s[p].z;
	int fx=g_fa(x),fy=g_fa(y);
	if(fx==fy) {Insert(z^xos[x]^xos[y]);return 0;}
	else {if(sz[fx]>sz[fy])swap(fx,fy);st[++tp]=fx;fa[fx]=fy;sz[fy]+=sz[fx];we[fx]=z^xos[x]^xos[y];return 1;}
}
void _past() {
	int fx=st[tp],fy=g_fa(fx);
	tp--;sz[fy]-=sz[fx];fa[fx]=fx;we[fx]=xos[fx]=0;
}
void solve(int x) {
	int nw[31],cnt=0;
	for(int i=up;i>=0;i--)nw[i]=Bs[i];
	for(int i=0;i<V[x].size();i++) {
		int p=V[x][i];
		cnt+=Union(p);
	}
	if(T[x].l==T[x].r) {
		int t=T[x].l;
		for(int i=0;i<Q[t].size();i++) {
			int u=Q[t][i].x,v=Q[t][i].y;
			int k=g_fa(u);k=g_fa(v);
			int d=xos[u]^xos[v];
			ans[t]=Mn(d);
		}
	}
	else {solve(x<<1);solve(x<<1|1);}
	while(cnt--) _past();
	for(int i=up;i>=0;i--)Bs[i]=nw[i];
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].z),s[i].t=1,s[i].opt=1;
	scanf("%d",&q);
	int tot=m;
	for(int i=1;i<=q;i++) {
		int opt,x,y;
		scanf("%d%d%d",&opt,&x,&y);
		if(opt==3) Q[i].push_back((node){x,y});
		else {
			s[++tot]=(query){opt,x,y,0,i};
			if(opt==1) {scanf("%d",&s[tot].z);}
		}
	}
	Build(1,1,q);
	sort(s+1,s+1+tot,cmp);
	for(int i=tot;i;i--) {
		if(s[i].opt==1) {
			if(i<tot&&s[i].x==s[i+1].x&&s[i].y==s[i+1].y) {if(s[i].t<s[i+1].t)Update(1,s[i].t,s[i+1].t-1,i);else continue;}
			else {Update(1,s[i].t,q,i);}
		}
	}
	for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1,xos[i]=we[i]=0;
	solve(1);
	for(int i=1;i<=q;i++)if(Q[i].size())printf("%d\n",ans[i]);
	return 0;
}