bzoj2322 梦想封印

Posted Scx117

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2322 梦想封印相关的知识,希望对你有一定的参考价值。

题意和题解见思路索引。

 

标程及易错点:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll read()
 5 {
 6     ll x=0;char ch=getchar();
 7     while (ch<0||ch>9) ch=getchar();
 8     while (0<=ch&&ch<=9) x=(x<<1)+(x<<3)+ch-0,ch=getchar();
 9     return x;
10 }
11 const int M=20005;
12 const int N=5005;
13 set<ll> s;
14 int cnt,head[N],blo,u[M],v[M],top,x,y,pos,vis[N],tag[M*2],n,m,Q,e[M];
15 ll ans[M],ww,w[N],base[65],q[N];
16 set<ll>::iterator it;
17 struct node{int to,next;ll w;}num[M*2];
18 void add(int x,int y,ll w)
19 {num[++cnt].to=y;num[cnt].next=head[x];num[cnt].w=w;head[x]=cnt;}
20 void ins(ll x)
21 {
22     if (!x) return;
23     for (int i=62;i>=0;i--)//从大到小 
24       if ((x>>i)&1) {base[i]=x;blo++;break;}    
25     for (top=0,it=s.begin();it!=s.end();++it) q[++top]=min(*it,*it^x);
26     s.clear(); 
27     for (int j=1;j<=top;j++) s.insert(q[j]);
28 }
29 ll match(ll x)
30 {
31     for (int i=62;i>=0&&x;i--)//从高位到低位消 
32       if ((x^base[i])<x) x^=base[i];//能消的位都消元 
33     return x;
34 }
35 void dfs(int x,int fa)
36 {
37    vis[x]=1;s.insert(match(w[x]));
38    for (int i=head[x];i;i=num[i].next)
39      if (num[i].to!=fa&&!tag[i])
40      {
41         if (!vis[num[i].to]) w[num[i].to]=w[x]^num[i].w,dfs(num[i].to,x);
42         else ins(match(w[x]^w[num[i].to]^num[i].w));//这里加环也要对set消元 
43      }    
44 }
45 int main()
46 {
47     n=read();m=read();Q=read();
48     for (int i=1;i<=m;i++) u[i]=read(),v[i]=read(),ww=read(),add(u[i],v[i],ww),add(v[i],u[i],ww);
49     for (int i=1;i<=Q;i++) e[i]=read(),tag[e[i]*2-1]=tag[e[i]*2]=1;
50     dfs(1,-1);
51     ans[Q+1]=(ll)s.size()*(1ll<<blo)-1; 
52     for (int i=Q;i>=1;i--)
53     {
54         tag[e[i]*2-1]=tag[e[i]*2]=0;
55         x=u[e[i]],y=v[e[i]],ww=num[e[i]*2].w;
56         if (vis[x]&&vis[y]) ins(match(w[x]^w[y]^ww));
57         else if (vis[x]) w[y]=w[x]^ww,dfs(y,x);
58         else if (vis[y]) w[x]=w[y]^ww,dfs(x,y);
59         ans[i]=(ll)s.size()*(1ll<<blo)-1;
60     }
61     for (int i=1;i<=Q+1;i++) printf("%lld\n",ans[i]);
62     return 0;
63 }

 

以上是关于bzoj2322 梦想封印的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2322[BeiJing2011]梦想封印 高斯消元求线性基+DFS+set

BZOJ 2322[BeiJing2011]梦想封印 利用"环基"+线性基特征值

NLP-万能语言打开语言的封印-神奇万能语言"人性大揭秘"谈笑间转变对方信念

BZOJ5251八省联考2018劈配(网络流,二分答案)

带有神秘附加字符的 Javascript Date getTime() 代码片段

bzoj2662:[BeiJing wc2012]冻结