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;
    }
    
  • 相关阅读:
    用mvc实现增删查改
    hibernate Annotation版本的helloworld
    hibernate 级联操作
    Hibrenate一对一外键关联
    hibernate主键生成
    Action属性接收参数
    WildCard的使用
    Struts 路径分析以及是否一定要执行excute()方法
    学习Struts2经验总结
    基于Struts分层web框架,研究传值问题
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8808484.html
Copyright © 2011-2022 走看看