zoukankan      html  css  js  c++  java
  • [Luogu3727]曼哈顿计划E

    luogu

    题意(简化版)

    给你一棵树,每个点上有一个(SG)值,问你是否存在一条路径使得(SG)异或和为(0)

    sol

    可以当做每个点的稳定值就是这个点上的石子数量。
    很显然我们只需要把每个点的(SG)值处理出来后面的就好做了。
    分别考虑(k)的不同取值下的(SG)函数的计算方法。

    (k=1)

    每堆石子可以任意取,显然(SG(x)=x)

    (k=2)

    打表/手玩可以发现,若(x)恰好为(S+1)的倍数(-1)(SG(x)=2),否则(SG(x)=x\%2)

    (k=3)

    打表/手玩可以发现,(SG(x)=lfloor frac{x}{S} floor)

    (k=4)
    打表可以发现,

    [SG(x)= egin{cases} 0 & ext{ , } x= 0 \ x & ext{ , } xequiv 1,2 (mod 4) \ x+1 & ext{ , } xequiv 3 (mod 4) \ x-1 & ext{ , } xequiv 0 (mod 4) end{cases} ]

    剩下的就很简单了,点分治每次考虑所有过重心的路径。开(set)记录每个点到分治重心的异或和,注意对重心的处理。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<set>
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 3e4+5;
    int T,n,k,s,to[N<<1],nxt[N<<1],head[N],cnt,val[N];
    int vis[N],sz[N],w[N],root,sum,val_top,fg;
    set<int>S;
    int SG(int x)
    {
    	if (k==1) return x;
    	if (k==2) return (x+1)%(s+1)?x&1:2;
    	if (k==3) return x/s;
    	if (k==4){
    		if (x==0) return 0;
    		if (x%4==1||x%4==2) return x;
    		if (x%4==3) return x+1;
    		else return x-1;
    	}
    }
    void link(int u,int v)
    {
    	to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
    }
    void getroot(int u,int f)
    {
    	sz[u]=1;w[u]=0;
    	for (int e=head[u];e;e=nxt[e])
    		if (to[e]!=f&&!vis[to[e]])
    		{
    			getroot(to[e],u);
    			sz[u]+=sz[to[e]];w[u]=max(w[u],sz[to[e]]);
    		}
    	w[u]=max(w[u],sum-sz[u]);
    	if (w[u]<w[root]) root=u;
    }
    void dfs1(int u,int f,int sta)
    {
    	if (S.find(sta^val_top)!=S.end()) fg=1;
    	for (int e=head[u];e;e=nxt[e])
    		if (to[e]!=f&&!vis[to[e]])
    			dfs1(to[e],u,sta^val[to[e]]);
    }
    void dfs2(int u,int f,int sta)
    {
    	S.insert(sta);
    	for (int e=head[u];e;e=nxt[e])
    		if (to[e]!=f&&!vis[to[e]])
    			dfs2(to[e],u,sta^val[to[e]]);
    }
    void solve(int u)
    {
    	vis[u]=1;S.insert(0);val_top=val[u];
    	for (int e=head[u];e;e=nxt[e])
    		if (!vis[to[e]])
    			dfs1(to[e],0,val[to[e]]),dfs2(to[e],0,val[to[e]]);
    	S.clear();
    	for (int e=head[u];e;e=nxt[e])
    		if (!vis[to[e]])
    		{
    			sum=sz[to[e]];root=0;
    			getroot(to[e],0);solve(root);
    		}
    }
    int main()
    {
    	T=gi();
    	while (T--)
    	{
    		n=gi();cnt=fg=0;
    		memset(head,0,sizeof(head));
    		memset(vis,0,sizeof(vis));
    		for (int i=1;i<n;++i)
    		{
    			int u=gi(),v=gi();
    			link(u,v);link(v,u);
    		}
    		for (int i=1;i<=n;++i) val[i]=gi();
    		k=gi();if (k==2||k==3) s=gi();
    		for (int i=1;i<=n;++i) val[i]=SG(val[i]);
    		root=0;w[0]=sum=n;
    		getroot(1,0);solve(root);
    		if (fg) puts("Mutalisk ride face how to lose?");
    		else puts("The commentary cannot go on!");
    	}
    	return 0;
    }
    
  • 相关阅读:
    std thread
    windows更新包发布地址
    How to set up logging level for Spark application in IntelliJ IDEA?
    spark 错误 How to set heap size in spark within the Eclipse environment?
    hadoop 常用命令
    windows 安装hadoop 3.2.1
    windows JAVA_HOME 路径有空格,执行软连接
    day01MyBatisPlus条件构造器(04)
    day01MyBatisPlus的CRUD 接口(03)
    day01MyBatisPlus入门(02)
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8808484.html
Copyright © 2011-2022 走看看