您的位置:首页 > 其它

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

2018-01-29 21:31 281 查看
  很容易想到离线加边并且把环和链拆开搞(就是对于每个终点求出起点到他的路径(其实就是dfs树),然后bzoj2115),而且维护也很简单,然而我们发现不同的终点可能得到相同的值,这就是我们遇到的最大的问题......继续观察,发现两个终点要么得到的值都不同要么得到的值都相同,所以我们就可以判断两个终点的链值的异或值(如果能被此时的"环基"搞出来就可以删掉一个),然后就60分......
  作为一名菜鸡,想到这里就去%题解了,发现我和题解的做法只有去重的时候不同......其实我们就是找到得到的值互不相同的终点的个数,也就是[对于目前的"环基",再插入链值,得到的线性基不同]的终点个数,然后我们发现对于每个终点,判断他们得到的线性基不同就是判断他们在"环基"里插入自己之后自己变成的值(需要经过上下消)不同,这样我们就能通过模拟插入过程得到每个值的"特征值",现在我们只需要找到特征值的种数就可以了(用个set就可以解决)!!!

#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
char xB[(1<<15)+10],*xS,*xT;
#define gtc (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)
inline void read(int &x){
register char ch=gtc;
for(x=0;ch<'0'||ch>'9';ch=gtc);
for(;ch>='0'&&ch<='9';x=(x<<1)+(x<<3)+ch-'0',ch=gtc);
}
typedef long long LL;
inline void Read(LL &x){
register char ch=gtc;
for(x=0;ch<'0'||ch>'9';ch=gtc);
for(;ch>='0'&&ch<='9';x=(x<<1)+(x<<3)+ch-'0',ch=gtc);
}
const int A=61,N=5010,M=20010;
#define bin(a,b) (((a)>>(b))&1)
std::set<LL>::iterator it;
LL temp
;
int len;
struct Gay{
int size;LL gay[A];std::set<LL> st;
inline LL trans(LL x,int begin){
for(int i=begin;i>=0;--i)
if(gay[i]&&bin(x,i))x^=gay[i];
return x;
}
inline void put(LL x){st.insert(trans(x,A-1));}
inline void insert(LL x){
for(int i=A-1;i>=0;--i){
if(!bin(x,i))continue;
if(gay[i])x^=gay[i];
else{gay[i]=x,++size,len=0;
for(it=st.begin();it!=st.end();++it)
temp[++len]=trans(*it,i);
st.clear();
for(int j=1;j<=len;++j)st.insert(temp[j]);
break;}
}
}
inline LL query(){
return st.size()*(1LL<<size)-1;
}
}gay;
struct V{int to,next;LL w;}c[M<<1];
struct E{int a,b;LL c;}e[M];
LL dis
,ans[M];
bool in
,die[M];
int head
,t,n,m,Q,sort[M];
inline void add(int x,int y,LL z){c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].w=z;}
inline void dfs(int x,int fa,LL val){
in[x]=true,dis[x]=val,gay.put(val);
for(int i=head[x];i;i=c[i].next)
if(in[c[i].to])gay.insert(c[i].w^dis[x]^dis[c[i].to]);
else dfs(c[i].to,x,val^c[i].w);
}
int main(){
read(n),read(m),read(Q);
register int i;int x;
for(i=1;i<=m;++i)read(e[i].a),read(e[i].b),Read(e[i].c);
for(i=1;i<=Q;++i)read(x),sort[i]=x,die[x]=true;
for(i=1;i<=m;++i)if(!die[i])add(e[i].a,e[i].b,e[i].c),add(e[i].b,e[i].a,e[i].c);
dfs(1,0,0);
for(i=Q;i>0;--i){
ans[i]=gay.query(),x=sort[i];
add(e[x].a,e[x].b,e[x].c),add(e[x].b,e[x].a,e[x].c);
if(in[e[x].a]==false&&in[e[x].b]==false)continue;
if(in[e[x].a]&&in[e[x].b])gay.insert(dis[e[x].a]^dis[e[x].b]^e[x].c);
else if(in[e[x].a])dfs(e[x].b,e[x].a,dis[e[x].a]^e[x].c);
else dfs(e[x].a,e[x].b,dis[e[x].b]^e[x].c);
}printf("%lld\n",gay.query());
for(i=1;i<=Q;++i)printf("%lld\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: