[BZOJ 2819]Nim
最近都忙的没空写题解了喵~
看到 1= 终于是保住了也算是一个小小的安慰吧 555……
湖北省队互测题,据说会爆栈,但 Linux 下 栈空间=内存=128M 真的吃不下?
反正我是写了个人工栈~
这似乎是我近 4 天里写的第 3 道树链剖分?
#include <cstdio>
#include <cstring>
#include <cstdlib>
const int sizeOfPoint=;
const int sizeOfEdge=; int n, m, q;
int w[sizeOfPoint];
int f[sizeOfPoint], d[sizeOfPoint], s[sizeOfPoint];
int num, idx[sizeOfPoint], top[sizeOfPoint], son[sizeOfPoint];
inline char getch();
inline int getint();
inline void putint(int); struct edge {int point; edge * next;};
edge memory[sizeOfEdge], * port=memory;
edge * e[sizeOfPoint];
inline edge * newedge(int, edge * );
inline void link(int, int); int tot, stack[sizeOfPoint];
edge * t[sizeOfPoint];
inline void dfsTree();
inline void dfsChain(); int T[sizeOfPoint<<];
inline void build();
inline void updateItem(int, int);
inline int querySegment(int, int); inline void swap(int & , int & );
inline int queryChain(int, int); int main()
{
char ch;
int u, v; n=getint();
for (int i=;i<=n;i++)
w[i]=getint();
for (int i=;i<n;i++)
{
int u=getint(), v=getint();
link(u, v);
} dfsTree();
dfsChain();
build(); q=getint();
for (int i=;i<=q;i++)
{
ch=getch(), u=getint(), v=getint(); if (ch=='Q') putint(queryChain(u, v));
else updateItem(idx[u], v);
} return ;
}
inline char getch()
{
register char ch;
do ch=getchar(); while (ch!='Q' && ch!='C');
return ch;
}
inline int getint()
{
register int num=;
register char ch;
do ch=getchar(); while (ch<'' || ch>'');
do num=num*+ch-'', ch=getchar(); while (ch>='' && ch<='');
return num;
}
inline void putint(int num)
{
if (num>) putchar('Y'), putchar('e'), putchar('s');
else putchar('N'), putchar('o');
putchar('\n');
}
inline edge * newedge(int point, edge * next)
{
edge * ret=port++;
ret->point=point; ret->next=next;
return ret;
}
inline void link(int u, int v)
{
e[u]=newedge(v, e[u]); e[v]=newedge(u, e[v]);
}
inline void dfsTree()
{
int u; memcpy(t, e, sizeof(e));
memset(d, 0xFF, sizeof(d)); d[]=;
s[]=;
for (stack[++tot]=;tot; )
{
u=stack[tot]; edge *& i=t[u];
for ( ;i && d[i->point]>=;i=i->next);
if (i)
{
stack[++tot]=i->point;
f[i->point]=u;
d[i->point]=d[u]+;
s[i->point]=;
}
else
{
if (!f[u]) break;
s[f[u]]+=s[u];
if (s[u]>s[son[f[u]]])
son[f[u]]=u;
tot--;
}
}
}
inline void dfsChain()
{
int u; memcpy(t, e, sizeof(e));
idx[]=num=; top[]=;
for (stack[++tot]=;tot; )
{
u=stack[tot];
if (son[u] && !idx[son[u]])
{
stack[++tot]=son[u];
idx[son[u]]=++num;
top[son[u]]=top[u];
continue;
} edge *& i=t[u];
for ( ;i && idx[i->point];i=i->next);
if (i)
{
stack[++tot]=i->point;
idx[i->point]=++num;
top[i->point]=i->point;
}
else
{
if (!f[u]) break;
tot--;
}
}
}
inline void build()
{
for (m=;m<n+;m<<=);
for (int i=;i<=n;i++) T[idx[i]+m]=w[i];
for (int i=m;i>=;i--) T[i]=T[i<<]^T[i<<|];
}
inline void updateItem(int i, int t)
{
for (T[i+=m]=t, i>>=;i;i>>=) T[i]=T[i<<]^T[i<<|];
}
inline int querySegment(int l, int r)
{
int sum=;
for (l=l+m-, r=r+m+;l^r^;l>>=, r>>=)
{
if (~l&) sum^=T[l^];
if ( r&) sum^=T[r^];
}
return sum;
}
inline void swap(int & u, int & v)
{
int t=u; u=v; v=t;
}
inline int queryChain(int u, int v)
{
int sum=;
while (top[u]!=top[v])
{
if (d[top[u]]<d[top[v]]) swap(u, v);
sum^=querySegment(idx[top[u]], idx[u]);
u=f[top[u]];
}
if (d[u]>d[v]) swap(u, v);
sum^=querySegment(idx[u], idx[v]);
return sum;
}
1A 好评如潮
[BZOJ 2819]Nim的更多相关文章
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- bzoj 2819 Nim(BIT,dfs序,LCA)
2819: Nim Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1596 Solved: 597[Submit][Status][Discuss] ...
- BZOJ 2819: Nim( nim + DFS序 + 树状数组 + LCA )
虽然vfleaking好像想卡DFS...但我还是用DFS过了... 路径上的石堆异或和=0就是必败, 否则就是必胜(nim游戏). 这样就变成一个经典问题了, 用DFS序+BIT+LCA就可以在O( ...
- [BZOJ 2819]NIM(dfs序维护树上xor值)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2819 分析: 树上的nim游戏,关键就是要判断树上的一条链的异或值是否为0 这个题目有 ...
- BZOJ 2819: Nim dfs序维护树状数组,倍增
1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...
- bzoj 2819 Nim dfn序+树状数组维护区间异或值
题目大意 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- BZOJ 2819 Nim 树链剖分+树状数组
这题真没什么意思. 不过就是将普通的求Min,Max,求和等东西换成Xor,偏偏Xor还有很多性质. 算是刷道水题吧. #include<iostream> #include<cst ...
- bzoj 2819(DFS序+树状数组+博弈+lca)
2819: Nim Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2045 Solved: 795[Submit][Status][Discuss] ...
- BZOJ:2819 NIM(树链剖分||DFS序 &&NIM博弈)
著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略的.于是v ...
随机推荐
- java多线程总结
java中的多线程 一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程.启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的.在进程 ...
- Xcode 7如何 免费 真机调试iOS应用
运行Xcode后,点击菜单中的Preferences…进入Accounts标签,这里选择添加Apple ID: 在弹出的对话框中登入你的Apple ID,没有的话去注册一个就是了,登录成功后会看到下面 ...
- VS2010默认属性文件配置
问题: 在VS2010中,同一个解决方案下有多个项目,都需要使用某一个库. 如果项目比较多,或者编译链接环境属性变动频繁,分别对项目进行配置就很麻烦. 解决: 在VS的配置文件中统一配置属性: 我的配 ...
- DataTable转Json字符串(使用Newtonsoft.Json.dll)
DataTable转Json字符串(使用Newtonsoft.Json.dll) 在需要把DataTable转为Json字符串时,自己手动拼接太麻烦,而且容易出错,费时费力,使用Newtonsoft. ...
- 【转】sql to_char 日期转换字符串
1.转换函数 与date操作关系最大的就是两个转换函数:to_date(),to_char() to_date() 作用将字符类型按一定格式转化为日期类型: 具体用法:to_date('2004-11 ...
- 浅谈Android系统移植、Linux设备驱动
一.Android系统架构 第一层:Linux内核 包括驱动程序,管理内存.进程.电源等资源的程序 第二层:C/C++代码库 包括Linux的.so文件以及嵌入到APK程序中的NDK代码 第三层:An ...
- ionic 使用
1. 编译时目录下不能有中文文件的名称,否则会报一个资源错误 ,返回aapt.exe'' finished with non-zero exit value 1. 2. 编译完成后在手机上无法访问网络 ...
- Java随笔二
1.常量:final可以设置变量,也可以表示这个变量只能被赋值一次(即可以声明一个空变量,只能赋值一次):可以使用关键字static final设置一个类常量,以供一个类中的多个方法使用. 2.字符串 ...
- strlen 字符型数组和字符数组 sizeof和strlen的区别 cin.get(input,Arsize)
strlenstrlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值 ...
- Python Django 数据库操作
1. 建立app 在自己的工程项目目录下输入: python manage.py startapp myapp(你想建立的app名称) 建立一个叫myapp的app 这样,在你的工程项目目录下会出现一 ...