Mn Zn刚学线段树分治求助
查看原帖
Mn Zn刚学线段树分治求助
107154
daduoli楼主2023/5/21 09:58

这个代码是60分的,就是带回删的。

#include<bits/stdc++.h>
#define bs bitset<1010>
typedef long long LL;

using namespace std;
const int MAXN=5010,NN=1000;
int n,m,q;
struct daduoli {
	int f,t;
	bitset<1010>c;
}que[MAXN*2];
int h[MAXN],cnt;
void add(int f,int t,bs c) {
	que[++cnt].f=h[f];
	que[cnt].t=t;
	que[cnt].c=c;
	h[f]=cnt;
}
bs dis[MAXN],ans[MAXN],d[MAXN],lslsls;
bool vis[MAXN];
int update(bs ls) {
	for(int i=NN;i>=0;--i) {
		if(ls[i]) {
			if(!d[i].any()) {
				d[i]=ls;
				return i;
			}
			else ls^=d[i];
		}
	}
	return -1;
}
void dfs(int node,bs ls) {
	dis[node]=ls;
	vis[node]=1;
	int asd=0;
	for(int i=h[node];i;i=que[i].f) {
		int t=que[i].t;
		if(vis[t]) asd=update(ls^que[i].c^dis[t]);
		else dfs(t,ls^que[i].c);
	}
}
bs qry() {
	bs nw;
	for(int i=NN;i>=0;--i) {
		if(!nw[i]) nw^=d[i];
	}
	return nw;
}
struct dl {
	int x,y;
	bs c;
}gt[MAXN*2];
vector<int> tree[MAXN*4];
int lt[MAXN*2],tot;
void insert(int node,int l,int r,int x,int y,int pp) {
	if(l>y||r<x) return ;
	if(l>=x&&r<=y) {
		tree[node].push_back(pp);
		return ;
	}
	int mid=(l+r)/2;
	insert((node<<1),l,mid,x,y,pp);
	insert((node<<1|1),mid+1,r,x,y,pp);
}
void dele(int x) {
	d[x].reset();
}
int ind[MAXN];
struct asd {
	int x,y,l,r;
	bs c;
}E[MAXN*4];
int zxc;
void solve(int node,int l,int r) {
	if(r<l) return ;
	int len=tree[node].size();
	int rt=zxc;
	for(int i=0;i<len;++i) {
		int tmp=update(E[tree[node][i]].c);
		if(tmp!=-1) {
			ind[++zxc]=tmp;
		}
	}
	if(l==r) {
		ans[l]=qry();
		return ;
	}
	int mid=(l+r)/2;
	solve((node<<1),l,mid);
	solve((node<<1|1),mid+1,r);
	while(zxc>rt) {
		d[ind[zxc]].reset();
		--zxc;
	}
}
int main () { 
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=m;++i) {
		int x,y;
		bs ls;
		cin>>x>>y>>ls;
		add(x,y,ls);
		add(y,x,ls);
	} cnt=0;
	dfs(1,lslsls);
	ans[0]=qry();
	for(int i=1;i<=q;++i) lt[i]=1;
	string opt;
	int x,y;
	bs ls;
	for(int i=1;i<=q;++i) {
		cin>>opt;
		if(opt[1]=='d') {
			cin>>x>>y>>ls;
			++tot;
			E[tot]=(asd){x,y,i,q,ls^dis[x]^dis[y]};
			lt[++cnt]=tot;
		}
		if(opt[1]=='h') {
			cin>>x>>ls;
			E[lt[x]].r=i-1;
			E[++tot]=(asd){E[lt[x]].x,E[lt[x]].y,i,q,ls^dis[E[lt[x]].x]^dis[E[lt[x]].y]};
			lt[x]=tot;
		}
		if(opt[1]=='a') {
			cin>>x;
			E[lt[x]].r=i-1;
			lt[x]=0;
		}
	}
	for(int i=1;i<=tot;++i) {
		insert(1,1,q,E[i].l,E[i].r,i);
	} tot=0;
	solve(1,1,q);
	for(int i=0;i<=q;++i) {
		bool sf=0;
		for(int j=NN;j>=0;--j) {
			if(ans[i][j]) sf=1;
			int tmp=ans[i][j]; 
			if(sf) printf("%d",tmp);
		}
		if(!sf) printf("0");
		printf("\n");
	}
	return 0;
}

下面这个不带回删,线段树上每个节点开一个线性基不知道为什么就能过,很奇怪

#include<bits/stdc++.h>
#define bs bitset<1010>
typedef long long LL;

using namespace std;
const int MAXN=5010,NN=1000;
int n,m,q;
struct daduoli {
	int f,t;
	bitset<1010>c;
}que[MAXN*2];
int h[MAXN],cnt;
void add(int f,int t,bs c) {
	que[++cnt].f=h[f];
	que[cnt].t=t;
	que[cnt].c=c;
	h[f]=cnt;
}
bs dis[MAXN],ans[MAXN],lslsls;
bool vis[MAXN];
struct asdsdad {
	bs a[1010];
}d;
int update(asdsdad &d,bs ls) {
	for(int i=NN;i>=0;--i) {
		if(ls[i]) {
			if(!d.a[i].any()) {
				d.a[i]=ls;
				return i;
			}
			else ls^=d.a[i];
		}
	}
	return -1;
}
void dfs(int node,bs ls) {
	dis[node]=ls;
	vis[node]=1;
	int asd=0;
	for(int i=h[node];i;i=que[i].f) {
		int t=que[i].t;
		if(vis[t]) asd=update(d,ls^que[i].c^dis[t]);
		else dfs(t,ls^que[i].c);
	}
}
bs qry(asdsdad d) {
	bs nw;
	for(int i=NN;i>=0;--i) {
		if(!nw[i]) nw^=d.a[i];
	}
	return nw;
}
struct dl {
	int x,y;
	bs c;
}gt[MAXN*2];
vector<bs> tree[MAXN*4];
int lt[MAXN*2],tot;
void insert(int node,int l,int r,int x,int y,bs pp) {
	if(l>y||r<x) return ;
	if(l>=x&&r<=y) {
		tree[node].push_back(pp);
		return ;
	}
	int mid=(l+r)/2;
	insert((node<<1),l,mid,x,y,pp);
	insert((node<<1|1),mid+1,r,x,y,pp);
}
int ind[MAXN];
void solve(int node,int l,int r,asdsdad bas) {
	if(r<l) return ;
	int len=tree[node].size();
	int rt=tot;
	for(int i=0;i<len;++i) {
		int tmp=update(bas,tree[node][i]);
		if(tmp!=-1) {
			ind[++tot]=tmp;
		}
	}
	if(l==r) {
		ans[l]=qry(bas);
		return ;
	}
	int mid=(l+r)/2;
	solve((node<<1),l,mid,bas);
	solve((node<<1|1),mid+1,r,bas);
}
int main () { 
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=m;++i) {
		int x,y;
		bs ls;
		cin>>x>>y>>ls;
		add(x,y,ls);
		add(y,x,ls);
	}
	dfs(1,lslsls);
	ans[0]=qry(d);
	for(int i=1;i<=q;++i) lt[i]=1;
	string opt;
	int x,y;
	bs ls;
	for(int i=1;i<=q;++i) {
		cin>>opt;
		if(opt[1]=='d') {
			cin>>x>>y>>ls;
			++tot;
			lt[tot]=i; gt[tot].x=x; gt[tot].y=y; gt[tot].c=ls;
		}
		if(opt[1]=='h') {
			cin>>x>>ls;
			insert(1,1,q,lt[x],i-1,dis[gt[x].x]^dis[gt[x].y]^gt[x].c);
			gt[x].c=ls;
			lt[x]=i;
		}
		if(opt[1]=='a') {
			cin>>x;
			insert(1,1,q,lt[x],i-1,dis[gt[x].x]^dis[gt[x].y]^gt[x].c);
			lt[x]=q+1;
		}
	}
	for(int i=1;i<=tot;++i) {
		insert(1,1,q,lt[i],q,dis[gt[i].x]^dis[gt[i].y]^gt[i].c);
	} tot=0;
	solve(1,1,q,d);
	for(int i=0;i<=q;++i) {
		bool sf=0;
		for(int j=NN;j>=0;--j) {
			if(ans[i][j]) sf=1;
			int tmp=ans[i][j]; 
			if(sf) printf("%d",tmp);
		}
		if(!sf) printf("0");
		printf("\n");
	}
	return 0;
}
2023/5/21 09:58
加载中...