每次操作实际上相当于把点到根上所有点消除。$O({n^2})$暴力显然,

用trie维护每棵子树的后继局面,然后需要进行trie树异或操作和tire树合并操作。

异或操作直接打标记

合并操作前,类似启发式合并,先把子树较小的的标记全部下放,然后全部按照另一棵的标记转好,然后把它合并到另一颗里面去。正确性因为有标记的地方都转过,再转一次就是原来的了。

复杂度$O(nlog^2n)$

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define drep(i, r, l) for (int i = r; i >= l; i--)
typedef long long ll;
const int N = 100008, D = 20;
int n, TOT, head[N], tot, fa[N], sg[N], a[N], rt[N], ans[N];
bool rev[N][D + 5];
struct Edge{int next, node;}e[N << 1];
int xgw;
inline void add(int x, int y)
{e[++TOT].next = head[x], head[x] = TOT, e[TOT].node = y;e[++TOT].next = head[y], head[y] = TOT, e[TOT].node = x;
}
struct Node
{int s[2], sum, sz;
}t[N * (D + 5)];
inline void updata(int x)
{t[x].sum = t[t[x].s[0]].sum + t[t[x].s[1]].sum;t[x].sz = 1 + (t[x].s[0] ? 1 : 0) + (t[x].s[1] ? 1 : 0);
}
void Insert(int u, int x, int d, int num)
{if (!d) {t[x].sum = 1; return;}int p = (num & (1 << d - 1)) ? 1 : 0;p ^= rev[u][d];if (!t[x].s[p]) t[x].s[p] = ++tot;Insert(u, t[x].s[p], d - 1, num);updata(x);
}
void calc(int u, int d, int num)
{if (!rt[u]) return;rep(i, 1, d) rev[u][i] ^= (num & (1 << i - 1)) ? 1 : 0;
}
int Find(int u, int x, int d, int cur)
{if (!x || !d) return cur;int ls = t[x].s[0 ^ rev[u][d]], rs = t[x].s[1 ^ rev[u][d]];//if (xgw) printf("->%d %d %d %d\n", u, d, t[ls].sum, t[rs].sum);if (t[ls].sum != (1 << d - 1)) return Find(u, ls, d - 1, cur);return Find(u, rs, d - 1, cur + (1 << d - 1));
}
void Turn(int u, int x, int d)
{if (!d || !x) return;if (rev[u][d]) swap(t[x].s[0], t[x].s[1]);Turn(u, t[x].s[0], d - 1);Turn(u, t[x].s[1], d - 1);
}
int Merge(int u, int x, int v, int y, int d)
{if (!d) return x;if (!x || !y) return x + y;rep(i, 0, 1) {int j = i ^ rev[u][d], k = i ^ rev[v][d];t[x].s[j] = Merge(u, t[x].s[j], v, t[y].s[k], d - 1);}updata(x);return x;
}
int MERGE(int u, int v)
{if (t[rt[u]].sz > t[rt[v]].sz) swap(u, v);Turn(u, rt[u], D);memcpy(rev[u], rev[v], sizeof(rev[v]));Turn(u, rt[u], D);return Merge(v, rt[v], u, rt[u], D);
}
void write(int u, int x, int d, int cur)
{if (!x) return;if (!d) {printf("%d ", cur); return;}int ls = t[x].s[0 ^ rev[u][d]], rs = t[x].s[1 ^ rev[u][d]];write(u, ls, d - 1, cur);write(u, rs, d - 1, cur + (1 << d - 1));
}
void dfs(int u)
{int Leaf = 1;for (int i = head[u], v; v = e[i].node, i; i = e[i].next)if (v != fa[u])Leaf = 0, fa[v] = u, dfs(v);if (Leaf) {sg[u] = !a[u]; if (sg[u]) Insert(u, rt[u] = ++tot, D, 0);  return;}int x = 0;for (int i = head[u], v; v = e[i].node, i; i = e[i].next)if (v != fa[u]){calc(u, D, sg[v]); calc(v, D, x);            rt[u] = MERGE(u, v);x ^= sg[v];}if (!a[u]) Insert(u, rt[u] ? rt[u] : rt[u] = ++tot, D, x);sg[u] = Find(u, rt[u], D, 0);
}
void Tour(int u, int cur)
{cur ^= sg[u];for (int i = head[u], v; v = e[i].node, i; i = e[i].next)if (v != fa[u]) cur ^= sg[v];if (!a[u] && !cur) ans[++ans[0]] = u;for (int i = head[u], v; v = e[i].node, i; i = e[i].next)if (v != fa[u]) Tour(v, cur);
}
void solve()
{dfs(1);//rep(i, 1, n) printf("[%d %d]\n", i, sg[i]);if (!sg[1]) printf("-1\n");else {Tour(1, sg[1]);sort(ans + 1, ans + ans[0] + 1);rep(i, 1, ans[0]) printf("%d\n", ans[i]); }
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
#endifscanf("%d", &n);rep(i, 1, n) scanf("%d", &a[i]);rep(i, 1, n - 1){int u, v; scanf("%d%d", &u, &v);add(u, v);}solve();
#ifndef ONLINE_JUDGEfclose(stdin); fclose(stdout);
#endifreturn 0;
}

View Code

转载于:https://www.cnblogs.com/Dyzerjet/p/4581676.html

BZOJ4134: ljw和lzr的hack比赛相关推荐

  1. 大鱼海棠_纪中4637_Trie维护Sg函数值

    Description 椿是掌管海棠花的少女,她所在的世界不为人们所知,他们的天空就是人类的海底.生活在那个世界里的他们不是人,也不是鱼,而是其他人,掌管着人间的规律. 按照他们的习俗,在16岁那年, ...

  2. 楼天成夺Facebook黑客杯季军,已被Facebook录用得到美国绿卡

    楼天成夺Facebook黑客杯季军,已被Facebook录用得到美国绿卡 [米联社·互联网]据科技博客TNW报道,Facebook举行的"黑客杯(Hacker Cup)大赛于今日(北京时间3 ...

  3. BestCoder Round #92 比赛记录

    上午考完试后看到了晚上的BestCoder比赛,全机房都来参加 感觉压力好大啊QAQ,要被虐了. 7:00 比赛开始了,迅速点进了T1 大呼这好水啊!告诉了同桌怎么看中文题面 然后就开始码码码,4分1 ...

  4. 给各位ACMer,OIer详细介绍一下Codeforces比赛

    Codeforces 简称: cf(所以谈论cf的时候经常被误会成TX的那款游戏). 网址: codeforces.com 这是一个俄国的算法竞赛网站,由来自萨拉托夫州立大学.由Mike Mirzay ...

  5. 人工智能/数据科学比赛汇总 2019.8

    内容来自 DataSciComp,人工智能/数据科学比赛整理平台. Github:iphysresearch/DataSciComp 本项目由 ApacheCN 强力支持. 微博 | 知乎 | CSD ...

  6. 1月全球CTF比赛时间汇总来了!

    ● 从事网络安全行业工作,怎么能不参加一次CTF比赛了! 小编作为一个CTF比赛老鸟,以每次都能做出签到题为荣! 下面给大家分享一下1月份CTF比赛时间,比赛按时间先后排序,国内国外的都有哦!临近新年 ...

  7. Nuit du hack 2017 webcrypto Writeup

    Nuit du hack 2017 web&crypto Writeup 新博客地址:http://bendawang.site/article/Nuit-du-hack-2017-web-a ...

  8. 武理校赛A题 ljw的剥削(思维 + map应用)

    武理校赛A题 ljw的剥削(思维 + map应用) 牛客链接 题意: 给定 a[],b[] 两个长度同为 n 的数组,经过一系列操作后, 使 p = ∑ i = 1 n m a x ( ( a i − ...

  9. Go Hack 17:Killy 日记

    "要是放在之前,我会觉得一个 hackathon 的二等奖也就只能说说,但是这次的质量让我觉得有种成就达成的感觉,于是决定把它放在我的简历里 =.=" 2017 年 10 月 21 ...

  10. 程序设计——第八周(差分约束:选数问题;拓扑排序:求比赛名次;scc:选班长)

    A.差分选数 题目描述 给定一个数轴上的 n 个区间,要求在数轴上选取最少的点使得第 i 个区间 [ai, bi] 里至少有 ci 个点 使用差分约束系统的解法解决这道题 使用差分约束系统的解法解决这 ...

最新文章

  1. IDEA配置GitHub和Gitee
  2. c#获取DataTable某一列不重复的值,或者获取某一列的所有值
  3. Hazelcast的MapLoader陷阱
  4. springmvc整合mybatis之准备阶段与文件配置
  5. hadoop linux 集群提交任务
  6. 锁屏界面提示某些设置已隐藏_OPPO忘记锁屏密码怎么办?教你一招轻松解开!...
  7. 开源 TiDB Operator 让 TiDB 成为真正的 Cloud-Native 数据库
  8. 控件readonly之后的取值
  9. 【二分答案】【NOIP模拟10-21】的士碰撞
  10. freemark 应用以及优势
  11. 阿里巴巴集团CEO张勇和校招生面对面,畅聊阿里的技术路线
  12. 观察数据时易出错的点
  13. 利用python制作词云图
  14. Andorid连接USB打印机
  15. word插入页眉、页码无法正常插入
  16. 别人的域名到期后可以抢注吗
  17. 明星隐私倒卖链:只要150 你对朱一龙行踪比他妈还了解
  18. 2022年电工(初级)考试报名及电工(初级)最新解析
  19. 基于Java的实时通信软件的设计(类似微信)
  20. 计算机微程序控制器实验报告,计算机组成原理实验报告三:微程序控制器实验.doc...

热门文章

  1. Java String、StringBuffer和StringBuilder的区别
  2. I Love ces(大小写字母转换 金马五校赛-上海大学)
  3. matlab画收敛曲线,3.26 面收敛处理
  4. hadoop 起动是的时候报错 localhost: Could not create the Java virtual machine._far beyond me,thks~~_百度空间...
  5. 程序员必备的十个工具
  6. Netty Websocket多人多房间聊天室Demo
  7. python删除列表第一个,在Python中删除列表的第一个元素
  8. 华为认证Datacom和Routing Switching方向的优势
  9. 信息技术领域会议(技术领域和非技术领域)
  10. 使用Python读取Windows注册表