• Luogu P4151 [WC2011]最大XOR和路径


    原题传送门
    看见异或最值,估计线性基跑不了了。
    考虑先随便提出一条从(1)(n)的路径,这显然不一定是最优的,但是可以让它变强。比如可以让它中间插入一个环来让它变优。比如说有一条路径:
    (1->A->B->C->N) 可以补成:
    (1->A->B->E->F->G->E->B->C->N)
    注意到权值的变化其实就是多异或了那个环上的异或和,然后一个线性基的模型就出来了。把所有的环丢到线性基里面去,然后和我们选出的这条路径异或取个最大值就可以了。但是有没有可能我们最先选出的路径限制了我们的答案,而选另一条路径更优呢?假设存在一条路径:(1->A->N),另一条路径为(1->B->N),那(1->A->N->B->1)就形成了一个环,前面那条路径异或这个环就变成了后者,反之亦然。于是正确性就保证了。

    #include <cstdio>
    using namespace std;
    #define R register
    #define LL long long
    const int MAXN=5e4+10;
    const int MAXM=2e5+10;
    const int MB=63;
    int n,m;
    struct Edge { int to,next; LL w; } e[MAXM];
    int head[MAXN],cnt;
    inline void add(int x,int y,LL w) {
    	e[++cnt]={y,head[x],w}; head[x]=cnt;
    }
    LL p[MB+1];
    inline void ins(LL x) {
    	for(R int i=MB;i>=0;i--)
    		if(x&(1LL<<i)) {
    			if(!p[i]) { p[i]=x; return ;}
    			else x^=p[i];
    		}
    }
    inline LL ask(LL x) {
    	for(R int i=MB;i>=0;i--)
    		if((x^p[i])>x) x^=p[i];
    	return x;
    }
    int vis[MAXN];
    LL res[MAXN];
    inline void dfs(int x,int fr,LL v) {
    	vis[x]=1; res[x]=v;
    	for(R int i=head[x];i;i=e[i].next) {
    		int y=e[i].to;
    		if(y==fr) continue;
    		if(vis[y]) ins(res[y]^res[x]^e[i].w);
    		else dfs(y,x,v^e[i].w);
    	}
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	for(R int i=1;i<=m;i++) {
    		int x,y; LL z;
    		scanf("%d%d%lld",&x,&y,&z);
    		add(x,y,z); add(y,x,z);
    	}
    	dfs(1,0,0);
    	printf("%lld
    ",ask(res[n]));
    	return 0;
    }
    
  • 相关阅读:
    【个人杂谈】MacBook Pro的使用心得
    【网页加速】lua redis的二次升级
    使用Openresty加快网页速度
    中间件——canal小记
    Java面试总结(二)
    RedissonLock分布式锁源码分析
    面试总结
    Spring AOP小记
    谈谈个人网站的建立(八)—— 缓存的使用
    Kafka、Logstash、Nginx日志收集入门
  • 原文地址:https://www.cnblogs.com/clover4/p/12818708.html
Copyright © 2020-2023  润新知