fzyzojP3372 -- [校内训练20171124]博弈问题


对于每个点都要答案
还是异或
trie树合并石锤了
朴素枚举是O(n^2*17)的
怎么办呢?
我们发现合并的时候,一些部分的trie的子树还是不变的
改变的部分也就是合并的复杂度可以接受
鉴于大部分trie都不变,而且是一个从上往下的过程,支持pushup维护
所以考虑dp,再在merge的pushup时候维护好dp值的更新
f[i]表示trie中以i为根子树,最后的游戏结果
转移分类讨论:
如果x的sz==1,令dp[x]=-1
否则如果仅x的某一个子树有sz,dp[x]=dp[son]
否则如果x的一个子树sz==1,那么先手一定选择这个子树,一定更优,那么后手的选择就固定了,就是在另一个子树trie上尽量使答案小。O(logn)转移一下
否则,那么先手进哪一个,后手一定跟进去,所以两个子树的dp取max即可
复杂度:O(nlog^2n)不严格
#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=+;
const int U=;//sudhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
int a[N];
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt;
int n;
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
struct tr{
int ls,rs;
int sz,dp;
int val;
}t[N*];
int tot;
int calc(int x,int d,int s){
int ret=;
int now=x;
for(reg i=d+;i<=U;++i){
int c=(s>>(U-i))&;
if(c==){
if(t[now].ls) now=t[now].ls;
else now=t[now].rs,ret+=(<<(U-i));
}else{
if(t[now].rs) now=t[now].rs;
else now=t[now].ls,ret+=(<<(U-i));
}
}
return ret;
}
void pushup(int x,int d){
t[x].sz=t[t[x].ls].sz+t[t[x].rs].sz;
if(t[x].sz==) t[x].val=t[t[x].ls].val+t[t[x].rs].val;
if(t[x].sz==){
t[x].dp=-;
}
if(!t[t[x].ls].sz){
t[x].dp=t[t[x].rs].dp;
}else if(!t[t[x].rs].sz){
t[x].dp=t[t[x].ls].dp;
}else{
if(t[t[x].ls].sz==){
t[x].dp=calc(t[x].rs,d+,t[t[x].ls].val)+(<<(U-d-));
}else if(t[t[x].rs].sz==){
t[x].dp=calc(t[x].ls,d+,t[t[x].rs].val)+(<<(U-d-));
}else{
t[x].dp=max(t[t[x].ls].dp,t[t[x].rs].dp);
}
}
}
void upda(int &x,int d,int v){
if(!x) x=++tot;
//cout<<" xx "<<x<<" d "<<d<<" v "<<v<<endl;
if(d==U){
++t[x].sz;
t[x].val=v;
if(t[x].sz==){
t[x].dp=-;
}else t[x].dp=;
return;
}
if(v&(<<(U-d-)))// cout<<"is 1",
upda(t[x].ls,d+,v);
else //cout<<"is 0 ",
upda(t[x].rs,d+,v);
pushup(x,d);
}
int merge(int x,int y,int d){
if(!x||!y) return x+y;
if(d==U){
t[x].sz+=t[y].sz;
t[x].dp=;
return x;
}
t[x].ls=merge(t[x].ls,t[y].ls,d+);
t[x].rs=merge(t[x].rs,t[y].rs,d+);
pushup(x,d);
return x;
}
int rt[N];
int ans[N];
void dfs(int x,int fa){
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
dfs(y,x);
rt[x]=merge(rt[x],rt[y],);
}
//cout<<" x "<<x<<" "<<rt[x]<<" : "<<t[rt[x]].dp<<" "<<t[rt[x]].sz<<endl;
upda(rt[x],,a[x]);
ans[x]=t[rt[x]].dp;
}
int main(){
rd(n);
for(reg i=;i<=n;++i)rd(a[i]);
int x,y;
for(reg i=;i<n;++i){
rd(x);rd(y);
add(x,y);add(y,x);
}
dfs(,);
for(reg i=;i<=n;++i){
printf("%d\n",ans[i]);
}
return ;
} }
signed main(){
freopen("3372.in","r",stdin);
freopen("3372.out","w",stdout);
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/2/3 17:19:49
*/
总结:
考虑在变化中寻找不变的,再进行维护
变化的毕竟在少数。
动态点分治就是这个思想。
要大胆DP
再认真分析维护的复杂度和方式。
也启示我们线段树不光是只能维护信息的存在与否。(其实都是靠pushup辣)
fzyzojP3372 -- [校内训练20171124]博弈问题的更多相关文章
- [4.14校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi.... 很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...
- [2017.4.7校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...
- [3.24校内训练赛by hzwer]
来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...
- 19_04_19校内训练[Game]
题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...
- 19_04_02校内训练[deadline]
题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...
- 平面图转对偶图&19_03_21校内训练 [Everfeel]
对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...
- fzyzojP3979 -- [校内训练20180914]魔法方阵
原题见CF632F https://blog.csdn.net/Steaunk/article/details/80217764 这个比较神仙了 点边转化, 把max硬生生转化成了路径最大值,再考虑所 ...
- fzyzojP3580 -- [校内训练-互测20180315]小基的高智商测试
题目还有一个条件是,x>y的y只会出现一次(每个数直接大于它的只有一个) n<=5000 是[HNOI2015]实验比较 的加强版 g(i,j,k)其实可以递推:g(i,j,k)=g(i- ...
- fzyjojP2963 -- [校内训练20161227]疫情控制问题
(题干中的废话已经划去) dp显而易见 收益为负数的可以直接扔掉不管.不要一定更优 子串问题,考虑SAM 建立广义SAM 尝试匹配,匹配到的位置的parent树祖先如果有完整的串,那么可以从这个串转移 ...
随机推荐
- zip命令详解
基础命令学习目录首页 好文链接:https://www.cnblogs.com/yinzhengjie/p/6247833.html 原文链接:https://www.cnblogs.com/ferr ...
- XSS攻击防御篇
前言 上篇文章中提到了 XSS 攻击,而且,也从几个方面介绍了 XSS 攻击带来的严重影响.那么,这篇文章中,主要是针对 XSS 攻击做一个基本的防御,看看可以通过几种方式来修复这个特别常见的安全 ...
- Homebrew -- 安装与使用
使用 React Native,必须安装的依赖有:Node.Watchman 和 React Native 命令行工具以及 Xcode. 推荐使用Homebrew来安装 Node 和 Watchman ...
- 论如何制做一个工程APP的测试内容
测试一般在软件开发过程中就已经开始进行了,测试越早.发现问题解决他的方案成本就越小.测试按照类型来区分可以划分为:单元测试,集成测试,系统测试.而OCUNIT是XCODE自带的单元测试工具.需要建立新 ...
- Daily Scrum (2015/11/4)
因为距离部署的时间临近,而之前我们的进度偏慢.这天晚上我们大多数成员几乎所有时间都用在了这个项目上,成果还算令人满意. 成员 今日任务 时间 明日任务 符美潇 1.修复了一个BUG,此BUG会导致所爬 ...
- 项目Beta冲刺(团队)第五天
1.昨天的困难 服务器得不到前端返回的数据 教务处网页的源代码的研究有些困难,有些具体数据还不能得到,jsoup还在探索 2.今天解决的进度 成员 进度 陈家权 点赞界面设计 赖晓连 问答功能各项完善 ...
- 【贪心算法】POJ-3262
一.题目 Description Farmer John went to cut some wood and left N (2 ≤ N ≤ 100,000) cows eating the gras ...
- JAVA异常架构图及常见面试题
红色为检查异常,就是eclipse要提示你是try catch 还是throws. 非检查异常,就是/0,nullpointexception,数据越界访问indexOfOutBounds 异常 错误 ...
- angularJS1笔记-(19)-angular异步加载包的方式
我们平时写的导入包的方式都是同步方式,有时候会显得过于卡顿,这样我们就可以使用异步加载的方式. script.js方式: 执行结果为: 异步加载还可以加载多个即为script([,,,],functi ...
- [转帖]select提高并发,select和poll、epoll的区别(杂)
同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. https://www.2cto.com/kf/20161 ...