_WA自动机 @ 2019-05-09 16:22:03
30分感觉很失败啊...有没有人康康这份代码哪里错了啊/kel
#include <cstdio>
#include <cstring>
#include <cstdint>
#include <cassert>
#include <algorithm>
#include <vector>
#define ls l,mid,o<<1
#define rs mid+1,r,o<<1|1
using std::vector;
const int maxn=1e5+1000;
vector<int> G[maxn];
int opr[maxn],opt[maxn];
int depth[maxn],fa[maxn],siz[maxn];
int top[maxn],son[maxn],id[maxn],cnt;
uint64_t f0[maxn<<2],f1[maxn<<2],g0[maxn<<2],g1[maxn<<2];
uint64_t val[maxn],w[maxn];
template<class T>inline void swap(T& a,T& b){a^=b^=a^=b;}
inline void dfs(int u,int ff,int dep)
{
depth[u]=dep;
fa[u]=ff;siz[u]=1;
int maxs=-1;
for (auto v:G[u])
{
if (v==ff) continue;
dfs(v,u,dep+1);
siz[u]+=siz[v];
if (siz[v]>=maxs) maxs=siz[v],son[u]=v;
}
}
inline void dfs(int u,int topf)
{
id[u]=++cnt;
val[cnt]=w[u];
opt[cnt]=opr[u];
top[u]=topf;
if (!son[u]) return;
dfs(son[u],topf);
for (auto v:G[u])
if (v!=fa[u] && v!=son[u]) dfs(v,v);
}
// 线段树 pushup操作
inline void pushup(int o)
{
f0[o]=((~f0[o<<1])&f0[o<<1|1])|(f0[o<<1]&f1[o<<1|1]);
f1[o]=((~f1[o<<1])&f0[o<<1|1])|(f1[o<<1]&f1[o<<1|1]);
g0[o]=((~g0[o<<1|1])&g0[o<<1])|(g0[o<<1|1]&g1[o<<1]);
g1[o]=((~g1[o<<1|1])&g0[o<<1])|(g1[o<<1|1]&g1[o<<1]);
}
inline uint64_t calc(uint64_t x,uint64_t y,int opt)
{
if (opt==1) return x&y;
if (opt==2) return x|y;
if (opt==3) return x^y;
// assert(0);
}
//线段树的建树
inline void build(int l,int r,int o)
{
if (l==r)
{
g0[o]=f0[o]=calc(0,val[l],opt[l]);
g1[o]=f1[o]=calc(UINT64_MAX,val[l],opt[l]);
return;
}
int mid=(l+r)>>1;
build(ls);build(rs);
pushup(o);
}
// 线段树的单点更新
inline void update(int pos,uint64_t v,int opt,int l,int r,int o)
{
if (l==r)
{
g0[o]=f0[o]=calc(0,v,opt);
g1[o]=f1[o]=calc(UINT64_MAX,v,opt);
return;
}
int mid=(l+r)>>1;
if (pos<=mid) update(pos,v,opt,ls);
else update(pos,v,opt,rs);
pushup(o);
}
// 从左到右的查询,对应lca->v的路径。
inline void query_ltr(int L,int R,int l,int r,int o,uint64_t& zero,uint64_t& one)
{
if (L<=l && R>=r)
{
zero=(zero&f1[o])|((~zero)&f0[o]);
one=(one&f1[o])|((~one)&f0[o]);
return;
}
int mid=(l+r)>>1;
if (L<=mid) query_ltr(L,R,ls,zero,one);
if (R> mid) query_ltr(L,R,rs,zero,one);
}
// 从右到左的查询,对应u->lca的路径
inline void query_rtl(int L,int R,int l,int r,int o,uint64_t& zero,uint64_t& one)
{
if (L<=l && R>=r)
{
zero=(zero&g1[o])|((~zero)&g0[o]);
one=(one&g1[o])|((~one)&g1[o]);
return;
}
int mid=(l+r)>>1;
if (R> mid) query_rtl(L,R,rs,zero,one);
if (L<=mid) query_rtl(L,R,ls,zero,one);
}
inline int LCA(int u,int v)
{
while (top[u]!=top[v])
{
if (depth[top[u]]<depth[top[v]]) swap(u,v);
u=fa[top[u]];
}
return depth[u]>depth[v]?v:u;
}
inline uint64_t query(int u,int v,uint64_t w,int n,int k)
{
int endpos=v;
static int stack[maxn];
uint64_t zero=0,one=UINT64_MAX;
int lca=LCA(u,v);
while (top[u]!=top[lca])
{
query_rtl(id[top[u]],id[u],1,n,1,zero,one);
u=fa[top[u]];
} // 此时u和lca在一条重链上。
if (u!=lca) query_rtl(id[top[u]]+1,id[u],1,n,1,zero,one); // 含lca的重链上除了u的节点
int cnt=0;
while (top[v]!=top[lca])
stack[++cnt]=top[v],v=fa[top[v]];
// stack是v到lca路径上所有的重链顶点
// 计算lca那半条重链答案的贡献
query_ltr(id[lca],id[v],1,n,1,zero,one);
// 计算每条整条的重链的贡献
for (int i=cnt;i>1;--i)
query_ltr(id[stack[i]],id[fa[stack[i-1]]],1,n,1,zero,one);
// 计算v那半条重链的贡献
if (cnt) query_ltr(id[stack[1]],id[endpos],1,n,1,zero,one);
// 按位贪心,ans是我最初应该填的数
uint64_t ans=0;
for (int i=k-1;~i;--i)
{
if ((1ull<<i)>w) continue;
if ((zero&(1ull<<i)) || !(one&(1ull<<i))) continue;
else if ((ans|(1ull<<i))<=w) ans|=1ull<<i;
}
return (((~ans)&zero)|(ans&one))&(k==64?UINT64_MAX:(((1ull<<k))-1));
}
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for (int i=1;i<=n;++i)
scanf("%d%lld",opr+i,w+i);
for (int i=1,u,v;i<n;++i)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0,1);dfs(1,1);build(1,n,1);
uint64_t z;
for (int i=1,x,y,opt;i<=m;++i)
{
scanf("%d%d%d%llu",&opt,&x,&y,&z);
if (opt&2) update(id[x],z,y,1,n,1);
else printf("%llu\n",query(x,y,z,n,k));
}
}
by 142857cs @ 2019-05-09 16:35:25
去你的萌新
by _WA自动机 @ 2019-05-09 16:40:06
@142857cs 诶别啊...我真的看不出来了才来这里发问的呢...后面别复读啊qwq
by 萌田薰子 @ 2019-05-09 16:42:49
Ynoi的题真的帮不到了Orz
by songyihang @ 2019-05-09 17:03:25
线段树是啥
by wxwoo @ 2019-05-09 17:22:03
树剖我会,线段树我会,Ynoi......再见
by mulberror @ 2019-05-09 17:58:36
去你的萌新
by NaCly_Fish @ 2019-05-09 18:01:04
@_WA自动机 这个30分是不是
by lukelin @ 2019-05-09 18:02:01
线段树是啥
by ferrum_cccp @ 2019-05-09 18:08:27
刚学树剖做云南省选?
by _WA自动机 @ 2019-05-09 18:16:28
@NaCly_Fish 大概是的吧...运行时间小于10ms...