Luogu3613 睡觉困难综合征

原题链接:https://www.luogu.org/problemnew/show/P3613

睡觉困难综合征

题目背景

刚立完Flag我就挂了WC和THUWC。。。

时间限制0.5s,空间限制128MB

因为Claris大佬帮助一周目由乃通过了Deus的题,所以一周目的由乃前往二周目世界找雪辉去了

由于二周目世界被破坏殆尽,所以由乃和雪辉天天都忙着重建世界(其实和MC差不多吧),Deus看到了题问她,总是被告知无可奉告

Deus没办法只能去三周目世界问三周目的由乃OI题。。。

三周目的世界中,因为没有未来日记,所以一切都很正常,由乃天天认真学习。。。

因为Deus天天问由乃OI题,所以由乃去学习了一下OI

由于由乃智商挺高,所以OI学的特别熟练

她在RBOI2016中以第一名的成绩进入省队,参加了NOI2016获得了金牌保送

Deus:这个题怎么做呀?

yuno:这个不是NOI2014的水题吗。。。

Deus:那如果出到树上,多组链询问,带修改呢?

yuno:诶。。。???

Deus:这题叫做睡觉困难综合征哟~

虽然由乃OI很好,但是她基本上不会DS,线段树都只会口胡,比如她NOI2016的分数就是100+100+100+0+100+100。。。NOIP2017的分数是100+0+100+100+0+100

所以她还是只能找你帮她做了。。。

题目描述

由乃这个问题越想越迷糊,已经达到了废寝忘食的地步。结果她发现……晚上睡不着了!只能把自己的一个神经元(我们可以抽象成一个树形结构)拿出来,交给Deus。

这个神经元是一个有n个点的树,每个点的包括一个位运算opt和一个权值x,位运算有&,l,^三种,分别用1,2,3表示。

为了治疗失眠,Deus可以将一些神经递质放在点x上,初始的刺激值是 v 0 。然后v依次经过从x到y的所有节点,每经过一个点i,v就变成v opti xi,所以他想问你,最后到y时,希望得到的刺激值尽可能大,所以最大值的v可以是多少呢?当然由于初始的神经递质的量有限,所以给定的初始值 v 0 必须是在[0,z]之间。Deus每次都会给你3个数,x,y,z。

不过,Deus为了提升治疗效果,可能会对一些神经节点进行微调。在这种情况下,也会给三个数x,y,z,意思是把x点的操作修改为y,数值改为z。

输入输出格式
输入格式:

第一行三个数n,m,k。k的意义是每个点上的数,以及询问中的数值z都 < 2 k 。之后n行,每行两个数x,y表示该点的位运算编号以及数值。

之后n - 1行,每行两个数x,y表示x和y之间有边相连。

之后m行,每行四个数,Q,x,y,z表示这次操作为Q(1位询问,2为更改),x,y,z意义如题所述。

输出格式:

对于每个操作1,输出到最后可以造成的最大刺激度v

输入输出样例
输入样例#1:

5 5 3
1 7
2 6
3 7
3 6
3 1
1 2
2 3
3 4
1 5
1 1 4 7
1 1 3 5
2 1 1 3
2 3 3 3
1 1 3 2

输出样例#1:

7
1
5

输入样例#2:

2 2 2
2 2
2 2
1 2
2 2 2 2
1 2 2 2

输出样例#2:

3

说明

对于30%的数据,n,m <= 1

对于另外20%的数据,k <= 5

对于另外20%的数据,位运算只会出现一种

对于100%的数据,0 <= n , m <= 100000 , k <= 64

题解

蒟蒻我一开始以为位运算什么的顺序不会有影响,样例都没玩就开始打, W A 成傻逼。。。

所以说,这道题最妙的地方就是, L C T 里维护的东西是对顺序有要求的,不同于和或者最大值是无序的。所以我们需要维护 S p l a y 里全 0 串和全 1 串中序遍历做完所有操作的结果的结果(为啥维护这个东西详见起床困难综合征)。

那么如何合并两个结果呢???

其实很简单,我们只需要把前面跑完后的是 0 的地方跟后面的全 0 串跑完的结果合并;同理,将 1 的地方跟后面的全 1 串合并。

0 串的合并与全 1 都是差不多的。

给出代码,配合理解:

sd merge(sd a,sd b)
{return (sd){(~a.s0&b.s0)|(a.s0&b.s1),(~a.s1&b.s0)|(a.s1&b.s1)};}

其他的就跟普通 L C T 起床困难综合征大同小异了,看代码即可。

代码
#include<bits/stdc++.h>
#define inf ULONG_LONG_MAX
#define ls son[v][0]
#define rs son[v][1]
#define ll unsigned long long
using namespace std;
const int M=1e5+5;
struct sd{ll s0,s1;}val[M],ab[M],ba[M];
sd merge(sd a,sd b){return (sd){(~a.s0&b.s0)|(a.s0&b.s1),(~a.s1&b.s0)|(a.s1&b.s1)};}
int son[M][2],dad[M],n,m,k;
bool rev[M];
void swap(sd &a,sd &b){sd c=a;a=b;b=c;}
bool notroot(int v){return son[dad[v]][0]==v||son[dad[v]][1]==v;}
void up(int v)
{
    ab[v]=ba[v]=val[v];
    if(ls)ab[v]=merge(ab[ls],ab[v]),ba[v]=merge(ba[v],ba[ls]);
    if(rs)ab[v]=merge(ab[v],ab[rs]),ba[v]=merge(ba[rs],ba[v]);
}
void turn(int v){swap(ab[v],ba[v]);swap(ls,rs);rev[v]^=1;}
void down(int v){if(rev[v]){if(ls)turn(ls);if(rs)turn(rs);rev[v]=0;}}
void push(int v){if(notroot(v))push(dad[v]);down(v);}
void spin(int v)
{
    int f=dad[v],ff=dad[f],k=son[f][1]==v,w=son[v][!k];
    if(notroot(f))son[ff][son[ff][1]==f]=v;son[v][!k]=f;son[f][k]=w;
    if(w)dad[w]=f;dad[f]=v;dad[v]=ff;
    up(f);
}
void splay(int v)
{
    push(v);int f,ff;
    while(notroot(v))
    {
        f=dad[v],ff=dad[f];
        if(notroot(f))spin((son[f][0]==v)^(son[ff][0]==f)?v:f);
        spin(v);
    }
    up(v);
}
void access(int v){for(int f=0;v;v=dad[f=v])splay(v),rs=f,up(v);}
void beroot(int v){access(v);splay(v);turn(v);}
void get(ll v,ll a,ll b)
{
    switch(a)
    {
        case 1:val[v]=(sd){0ull,b};break;
        case 2:val[v]=(sd){b,inf};break;
        case 3:val[v]=(sd){b,~b};
    }
}
void in()
{
    ll a,b;
    scanf("%d%d%d",&n,&m,&k);--k;
    for(int i=1;i<=n;++i){scanf("%llu%llu",&a,&b);get(i,a,b);}
    for(int i=1;i<n;++i){scanf("%llu%llu",&a,&b);beroot(a);dad[a]=b;}
}
ll work(ll a,ll b,ll c)
{
    beroot(a);access(b);splay(b);
    ll p0=ab[b].s0,p1=ab[b].s1,p,ans=0ull,w=0ull;
    for(int i=k;i>=0;--i)
    {
        p=1ull<<i;
        if(p0&p)ans+=p;
        else if((c>=p)&&(p1&p))ans+=p,c-=p;
    }
    return ans;
}
void ac()
{
    ll op,a,b,c;
    for(int i=1;i<=m;++i)
    {
        scanf("%llu%llu%llu%llu",&op,&a,&b,&c);
        if(op==1)printf("%llu\n",work(a,b,c));
        else splay(a),get(a,b,c),up(a);
    }
}
int main(){in();ac();}

猜你喜欢

转载自blog.csdn.net/shadypi/article/details/80846565