删边变加边
如果加的是非树边 相当于加了一个环 加入线性基中
如果加入的是树边 就dfs扩展树
两条链是等价的 相当于 他们用线性基消过后是一样的 用set维护
解是不等价链的个数*1<<线性基的个数-1
减一是要去掉0
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline void read(ll &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=5005;
const int M=20005;
const int K=63;
struct edge{
int u,v,next; ll w;
}G[M<<1]; int can[M<<1];
int head[N],inum=1;
inline void add(int u,int v,ll w,int p){
G[p].u=u; G[p].v=v; G[p].w=w; G[p].next=head[u]; head[u]=p;
}
int n,m;
ll depth[N]; int vst[N];
ll a[M<<1]; int tot,base[K+5];
inline ll Ext(ll x){
for (int p=K;~p;p--)
if (x>>p&1)
if (base[p])
x^=a[base[p]];
return x;
}
inline void Ins(ll x){
for (int p=K;~p;p--)
if (x>>p&1)
if (base[p])
x^=a[base[p]];
else{
a[base[p]=++tot]=x; return;
}
}
ll chain[N]; int cnt;
inline ll calc()
{
set<ll> Set;
int pnt=0;
for (int i=1;i<=cnt;i++)
{
ll x=Ext(chain[i]);
if (Set.find(x)==Set.end())
chain[++pnt]=chain[i],Set.insert(x);
}
cnt=pnt;
return (ll)cnt*(1LL<<tot)-1;
}
#define V G[p].v
inline void dfs(int u,int fa){
vst[u]=1; chain[++cnt]=depth[u];
for (int p=head[u];p;p=G[p].next)
if (V!=fa && !can[p])
{
if (!vst[V])
depth[V]=depth[u]^G[p].w,dfs(V,u);
else
Ins(depth[V]^depth[u]^G[p].w);
}
}
int Q,ed[M];
ll ans[M];
int main()
{
int iu,iv; ll iw;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m); read(Q);
for (int i=1;i<=m;i++)
read(iu),read(iv),read(iw),add(iu,iv,iw,++inum),add(iv,iu,iw,++inum);
for (int i=1;i<=Q;i++) read(ed[i]),can[ed[i]<<1]=can[ed[i]<<1|1]=1;
// for (int i=Q;i>=Q-10;i--) printf("%d %d %d\n",G[ed[i]<<1].u,G[ed[i]<<1].v,G[ed[i]<<1].w);
dfs(1,0);
ans[Q+1]=calc();
for (int i=Q;i;i--)
{
iu=G[ed[i]<<1].u; iv=G[ed[i]<<1].v;
if (vst[iu] && vst[iv]) Ins(depth[iv]^depth[iu]^G[ed[i]<<1].w);
if (vst[iu] && !vst[iv]) depth[iv]=depth[iu]^G[ed[i]<<1].w,dfs(iv,iu);
if (!vst[iu] && vst[iv]) depth[iu]=depth[iv]^G[ed[i]<<1].w,dfs(iu,iv);
can[ed[i]<<1]=can[ed[i]<<1|1]=0;
ans[i]=calc();
}
for (int i=1;i<=Q+1;i++)
printf("%lld\n",ans[i]);
return 0;
}