【BZOJ 2322】[BeiJing2011]梦想封印 利用"环基"+线性基特征值
2018-01-29 21:31
281 查看
很容易想到离线加边并且把环和链拆开搞(就是对于每个终点求出起点到他的路径(其实就是dfs树),然后bzoj2115),而且维护也很简单,然而我们发现不同的终点可能得到相同的值,这就是我们遇到的最大的问题......继续观察,发现两个终点要么得到的值都不同要么得到的值都相同,所以我们就可以判断两个终点的链值的异或值(如果能被此时的"环基"搞出来就可以删掉一个),然后就60分......
作为一名菜鸡,想到这里就去%题解了,发现我和题解的做法只有去重的时候不同......其实我们就是找到得到的值互不相同的终点的个数,也就是[对于目前的"环基",再插入链值,得到的线性基不同]的终点个数,然后我们发现对于每个终点,判断他们得到的线性基不同就是判断他们在"环基"里插入自己之后自己变成的值(需要经过上下消)不同,这样我们就能通过模拟插入过程得到每个值的"特征值",现在我们只需要找到特征值的种数就可以了(用个set就可以解决)!!!
作为一名菜鸡,想到这里就去%题解了,发现我和题解的做法只有去重的时候不同......其实我们就是找到得到的值互不相同的终点的个数,也就是[对于目前的"环基",再插入链值,得到的线性基不同]的终点个数,然后我们发现对于每个终点,判断他们得到的线性基不同就是判断他们在"环基"里插入自己之后自己变成的值(需要经过上下消)不同,这样我们就能通过模拟插入过程得到每个值的"特征值",现在我们只需要找到特征值的种数就可以了(用个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; }
相关文章推荐
- BZOJ 2322 BeiJing2011 梦想封印 高斯消元
- BZOJ 2322: [BeiJing2011]梦想封印
- BZOJ2322: [BeiJing2011]梦想封印
- BZOJ2322 [BeiJing2011]梦想封印 【set + 线性基】
- [高斯消元 线性基 树 记数] BZOJ 2322 [BeiJing2011]梦想封印
- 【BZOJ2322】[BeiJing2011]梦想封印 高斯消元求线性基+DFS+set
- BZOJ 2322 BeiJing2011 梦想封印
- BZOJ2322: [BeiJing2011]梦想封印 线性基
- [bzoj2322][线性基]梦想封印
- BZOJ2457 BeiJing2011 双端队列
- 【BZOJ 2321】 [BeiJing2011集训]星器
- BZOJ 2460 [BeiJing2011]元素 拟阵+极大线性无关组
- bzoj 2458: [BeiJing2011]最小三角形 题解
- bzoj 2461: [BeiJing2011]符环
- bzoj 2461: [BeiJing2011]符环
- bzoj2461 [BeiJing2011]符环 dp
- BZOJ 2460 [BeiJing2011]元素 线性基入门
- Bzoj2460 [BeiJing2011]元素
- 线性基(bzoj 2460: [BeiJing2011]元素)
- BZOJ 2460 [BeiJing2011]元素 ——线性基