【BZOJ】【2819】NIM
这题……咋说捏,其实是一道披着博弈论外衣的树上操作问题……
随便用dfs序或者树链剖分转成序列,然后查询路径上的所有点的NIM和(异或和)就行了,毕竟除了是在树上以外,就是裸的NIM问题。
树链剖分:一开始把线段树写跪了,然后输出“Yes”和“No”的时候全部大写了,再然后发现线段树空间开小了……
代码如下:
//BZOJ 2819
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
const int N=;
#define debug
int n,a[N],t[N<<],fa[N],top[N],dep[N],son[N],size[N],tid[N],cnt=;
vector<int>G[N];
bool vis[N]; #define mid (l+r>>1)
#define L (o<<1)
#define R (o<<1|1)
void updata(int o,int l,int r,int pos,int v){
if (l==r) t[o]=v;
else{
if (pos<=mid) updata(L,l,mid,pos,v);
else updata(R,mid+,r,pos,v);
t[o]=t[L]^t[R];
}
} int ql,qr,ans=;
void query_it(int o,int l,int r){
if (ql<=l && qr>=r) ans^=t[o];
else{
if (ql<=mid) query_it(L,l,mid);
if (qr>mid) query_it(R,mid+,r);
}
}
//segment tree end void dfs(int x,int f,int deep){
int y,maxsize=;
vis[x]=; fa[x]=f; dep[x]=deep; size[x]=; son[x]=;
rep(i,G[x].size()){
y=G[x][i];
if (vis[y]) continue;
dfs(y,x,deep+);
size[x]+=size[y];
if (size[y]>maxsize) maxsize=size[y],son[x]=y;
}
} void connect(int x,int f){
tid[x]=++cnt;
top[x]=f; vis[x]=;
if (son[x]) connect(son[x],f);
rep(i,G[x].size()){
int y=G[x][i];
if (!vis[y]) connect(y,y);
}
} void query(int x,int y){
while(top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
ql=tid[top[x]]; qr=tid[x];
query_it(,,n);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
ql=tid[x]; qr=tid[y];
query_it(,,n);
} int main(){
// freopen("file.in","r",stdin);
scanf("%d",&n);
F(i,,n) scanf("%d",&a[i]);
int x,y;
F(i,,n){
scanf("%d%d",&x,&y);
G[x].pb(y);
G[y].pb(x);
}
dfs(,,);
memset(vis,,sizeof vis);
connect(,);
F(i,,n) updata(,,n,tid[i],a[i]);
int q;
scanf("%d",&q);
char cmd[];
F(i,,q){
scanf("%s%d%d",cmd,&x,&y);
if (cmd[]=='Q'){
ans=;
query(x,y);
printf(ans ? "Yes\n" : "No\n");
}
else updata(,,n,tid[x],y);
}
return ;
}
dfs序版:
维护从根到x的异或和sum(x),则query(x,y)=sum(x)^sum(y)^a[lca(x,y)]
自己画个图一眼就看出来了……公共部分两次异或互相抵消,但是LCA是在x-->y这条路径上的,所以要再加上
/**************************************************************
Problem: 2819
User: Tunix
Language: C++
Result: Accepted
Time:15004 ms
Memory:65740 kb
****************************************************************/ //BZOJ 2819
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
void read(int &v){
v=; int sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
v*=sign;
}
/******************tamplate*********************/
const int N=;
int head[N],to[N<<],next[N<<],cnt,fa[N];
void add(int x,int y){
to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt;
}
/*******************edge***********************/
int n,m,dfs_clock,l[N],r[N],t[N<<],a[N],deep[N];
int st[N],top;
void dfs(){
st[++top]=; fa[]=;deep[]=;
while(top){
int x=st[top];
if (!l[x]){
l[x]=++dfs_clock;
for(int i=head[x];i;i=next[i])
if (to[i]!=fa[x]){
st[++top]=to[i];
fa[to[i]]=x;
deep[to[i]]=deep[x]+;
}
}
else{
r[x]=++dfs_clock;
top--;
}
}
}
int p[N][];
void ST(){
memset(p,-,sizeof p);
F(i,,n) p[i][]=fa[i];
for(int j=;(<<j)<=n;++j)
F(i,,n)
if (p[i][j-]!=-) p[i][j]=p[p[i][j-]][j-];
}
int lca(int x,int y){
if (deep[x]<deep[y]) swap(x,y);
int k=log(deep[x])/log();
D(i,k,)
if (deep[x]-(<<i)>=deep[y]) x=p[x][i];
if (x==y) return y;
D(i,k,)
if (p[x][i]!=- && p[x][i]!=p[y][i]){
x=p[x][i]; y=p[y][i];
}
return p[x][];
}
/*****************dfs&LCA***********************/
inline int lowbit(int x){return x&(-x);}
void update(int x,int val){
for(x;x<=n*;x+=lowbit(x)) t[x]^=val;
}
int sum(int x){
int temp=;
for(x;x;x-=lowbit(x)) temp^=t[x];
return temp;
}
/*********************fenwick*******************/
int main(){
read(n);
F(i,,n) read(a[i]);
int x,y;
F(i,,n){
read(x); read(y);
add(x,y);
}
dfs();
ST();
F(i,,n) update(l[i],a[i]),update(r[i],a[i]);
read(m);
char cmd[];
F(i,,m){
scanf("%s",cmd);
read(x); read(y);
if (cmd[]=='Q') printf( sum(l[y])^sum(l[x])^a[lca(x,y)] ? "Yes\n" : "No\n");
else{
update(l[x],a[x]); update(r[x],a[x]);
update(l[x],y); update(r[x],y);
a[x]=y;
}
}
return ;
}
【BZOJ】【2819】NIM的更多相关文章
- 【Bzoj 1835 基站选址】
基站选址的区间里隐藏着DP优化的机密…… 分析: 不论是做过乘积最大还是石子合并,或者是其他的入门级别的区间DP题目的人呐,大米并认为读题后就能够轻松得出一个简洁明了的Dp转移方程. ...
- 【BZOJ 2744 朋友圈】
Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1570 Solved: 532[Submit][Status][Discuss] Descripti ...
- 【BZOJ 5038 不打兔子】
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 22 Solved: 8[Submit][Status][Discuss] Description 勤 ...
- 【BZOJ 1088 扫雷Mine】模拟
http://www.lydsy.com/JudgeOnline/problem.php?id=1088 2*N的扫雷棋盘,第二列的值a[i]记录第 i 个格子和它8连通的格子里面雷的数目. 第一列的 ...
- 【BZOJ做题记录】07.07~?
在NOI一周前重开一个坑 最后更新时间:7.08 07:38 7.06 下午做的几道CQOI题: BZOJ1257: [CQOI2007]余数之和sum:把k mod i写成k-k/i*i然后分段求后 ...
- 【bzoj5050】【bzoj九月月赛H】建造摩天楼
讲个笑话,这个题很休闲的. 大概是这样的,昨天看到这个题,第一眼星际把题目看反了然后感觉这是个傻逼题. 后来发现不对,这个修改一次的影响是很多的,可能导致一个数突然可以被改,也可能导致一个数不能被改. ...
- 【BZOJ 4151 The Cave】
Time Limit: 5 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 293 Solved: 144[Submit][Status][Di ...
- 【BZOJ 2458 最小三角形】
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1551 Solved: 549[Submit][Status][Discuss] Descripti ...
- 【BZOJ 5000 OI树】
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 107 Solved: 64[Submit][Status][Discuss] Description ...
- 【BZOJ 5047 空间传送装置】
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 282 Solved: 121[Submit][Status][Discuss] Descriptio ...
随机推荐
- Zend studio 12.5.1破解过程
开始学习php了 今天又安装了一下Zend 之前找了很久的教程终于成了 , 今天换了一台电脑需要重新安装一下 又点忘记了. 就讲这个过程写下来 1.安装zend studio 12.5.1.这个过程 ...
- javaScript中的数组迭代方法
ECMAScript5为数组定义了5个迭代方法. 每个方法都接收两个参数:要在每一项上运行的函数 和 (可选的)运行该函数的作用域对象. 传入这些方法中的函数会接收三个参数:数组项的值,该项在数组 ...
- 《samba服务搭建》RHEL6
Samba服务不仅可以实现linux和win之间的文件共享,也可以实现linux和linux之间的共享,samba的用户只限服务端本地用户使用. 本文的环境是selinux开启的情况下配置 Samba ...
- WP开发笔记——WP APP添加页面跳转动画
微软的toolkit团队为我们为我们提供了这样一套组件,叫做TransitionServices服务. 简单说一下它具备的效果: turnstile(轴旋转效果): turnstile feather ...
- SQL server数据库内置账户SA登录设置
SQL server数据库内置账户SA登录不了 设置SQL Server数据库给sa设置密码的时候 提示18456 解决步骤: 第二步:右击sa,选择属性: 第三步:点击状态选项卡:勾选授予 ...
- 安装node和grunt
由于我用的恶事win8的系统,所以在安装nodeJS的时候出现了2503和2502的错误.解决方案: 进入cmd,然后输入msiexec /package [路径:为你将要安装的node所在的位置] ...
- 七天学会NodeJS-学习笔记
在网上发现一篇nodeJS教程,名为七天学会NodeJS,标题很有吸引力.我不指望七天能学会,只希望可以入门,下面是我的学习笔记和遇到的问题. 教程网址:http://nqdeng.github.io ...
- hi,mongo!(1)
用了很多年的关系型数据库,想换一种思路,学习一下最近比较火的mongo数据库. 一.下载.安装mongo 下载地址:http://www.mongodb.org/downloads(官网) 官网的mo ...
- 如何使用js捕获css3动画
如何使用js捕获css3动画 css3动画功能强大,但是不像js,没有逐帧控制,但是可以通过js事件来确定任何动画的状态. 下面是一段css3动画代码: #anim.enable{ -webkit-a ...
- 【面试虐菜】—— JAVA面试题(3)
1 throws与throw的区别 解析:throws和throw是异常处理时两个常见的关键字,初级程序员常常容易正确理解throw和throws的作用和区别,说明已经能比较深入理解异常处理.Thro ...