洛谷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依次经过从x到y的所有节点,每经过一个点i,v就变成v opti xi,所以他想问你,最后到y时,希望得到的刺激值尽可能大,所以最大值的v可以是多少呢?当然由于初始的神经递质的量有限,所以给定的初始值必须是在[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

树 LCT 位运算 贪心

略神的题。

基本的操作@NOI2014起床困难综合征

出到树上的话,用bitset存结点的真值表,用LCT维护一下树链,update的时候合并真值表即可。

要注意的是,LCT在reverse的时候左右子树,update的运算顺序会与实际不符。为了维护正确顺序,需要同时更新链上正向运算真值表和反向运算真值表,交换子树的时候把真值表交换。

↑否则WA一半数据(居然只有一半)

 1 5 10 5
 2 2 4
 3 1 9
 4 3 9
 5 3 15
 6 1 7
 7 1 2
 8 1 4
 9 2 5
10 2 3
11 1 1 3 31
12 1 1 5 31
13 1 4 3 28
14 1 3 4 28
15 1 5 4 27
16 1 4 5 27
17 1 5 4 27
18 1 4 3 28
19 1 3 4 28
hack

↑由于这个贪心顺序的问题,reverse的时候不能打个lazy标记就走,需要向下push一层。没注意到这个问题,多调了一个小时。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<cmath>
  6 #include<bitset>
  7 #include<vector>
  8 #define LL unsigned long long
  9 using namespace std;
 10 const int mxn=100010;
 11 LL read(){
 12     LL x=0,f=1;char ch=getchar();
 13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
 15     return x*f;
 16 }
 17 vector<int>ve[mxn];
 18 struct node{
 19     int ch[2],fa;
 20     LL val;
 21     int tp;//位运算方式  
 22     bool rev;
 23 }t[mxn];
 24 struct table{
 25     bitset<64>f[2];//真值表 //哪些位置填0/1能得到1
 26 }a[mxn],b[mxn],f[mxn];
 27 inline bool isroot(int x){
 28     return t[t[x].fa].ch[0]!=x && t[t[x].fa].ch[1]!=x;
 29 }
 30 void init(bitset<64> &a,LL b,int tp){
 31     bitset<64> B=b;
 32     if(tp==1){a=a&B;}//&
 33     else if(tp==2){a=a|B;}//|
 34     else if(tp==3){a=a^B;}//^
 35     return;
 36 }
 37 table calc(const table &x,const table &y){
 38     bitset<64>B,C;
 39     B=(x.f[0]&y.f[1])|((~x.f[0])&y.f[0]);
 40     C=(x.f[1]&y.f[1])|((~x.f[1])&y.f[0]);
 41     return (table){B,C};
 42 }
 43 void update(int rt){
 44     a[rt]=f[rt];b[rt]=f[rt];
 45     int ls=t[rt].ch[0],rs=t[rt].ch[1];
 46     if(ls){
 47         a[rt]=calc(a[ls],a[rt]);b[rt]=calc(b[rt],b[ls]);
 48     }
 49     if(rs){
 50         a[rt]=calc(a[rt],a[rs]);b[rt]=calc(b[rs],b[rt]);
 51     }
 52     return;
 53 }
 54 void rever(int x){
 55     t[x].rev^=1;
 56     int &lc=t[x].ch[0],&rc=t[x].ch[1];
 57     swap(lc,rc);
 58     swap(a[x],b[x]);    
 59     return;
 60 }
 61 void PD(int x){
 62     if(t[x].rev){
 63         rever(t[x].ch[0]);
 64         rever(t[x].ch[1]);
 65         t[x].rev=0;
 66     }
 67     return;
 68 }
 69 void rotate(int x){
 70     int y=t[x].fa,z=t[y].fa,lc,rc;
 71     if(t[y].ch[0]==x)lc=0;else lc=1; rc=lc^1;
 72     if(!isroot(y))
 73         t[z].ch[t[z].ch[1]==y]=x;
 74     t[x].fa=z;t[y].fa=x;
 75     t[t[x].ch[rc]].fa=y;
 76     t[y].ch[lc]=t[x].ch[rc];
 77     t[x].ch[rc]=y;
 78     update(y);
 79     return;
 80 }
 81 int st[mxn],top=0;
 82 void Splay(int x){
 83     st[top=1]=x;
 84     for(int i=x;!isroot(i);i=t[i].fa)st[++top]=t[i].fa;
 85     while(top)PD(st[top--]);
 86     while(!isroot(x)){
 87         int y=t[x].fa,z=t[y].fa;
 88         if(!isroot(y)){
 89             if((t[y].ch[0]==x)^(t[z].ch[0]==y))rotate(y);
 90             else rotate(x);
 91         }
 92         rotate(x);
 93     }
 94     update(x);
 95     return;
 96 }
 97 void access(int x){
 98     for(int y=0;x;x=t[x].fa){
 99         Splay(x);
100         t[x].ch[1]=y;
101         update(x);
102         y=x;
103     }
104     return;
105 }
106 int dfn[mxn];
107 void mkroot(int x){
108     access(x);Splay(x);
109     rever(x);
110     return;
111 }
112 void change(int x,int y,LL z){
113     access(x);   Splay(x);
114     t[x].tp=y;  t[x].val=z;
115     f[x].f[1].set(); f[x].f[0].reset();
116     init(f[x].f[0],t[x].val,t[x].tp);
117     init(f[x].f[1],t[x].val,t[x].tp);
118     update(x);
119     return;
120 }
121 void query(int x,int y,LL z){
122     mkroot(x);access(y);Splay(y);
123     LL ans=0,now=0;
124     for(int i=63;i>=0;i--){
125         if(a[y].f[0][i]==1){
126             ans+=1LL<<i;
127         }
128         else if(a[y].f[1][i]==1){
129             if(now+(1LL<<i)<=z){
130                 now+=1LL<<i;
131                 ans+=1LL<<i;
132             }
133         }
134     }
135     printf("%llu
",ans);
136     return;
137 }
138 int n,m,K;
139 void solve(){
140     int Q,x,y;LL z;
141     for(int i=1;i<=m;i++){
142         Q=read();x=read();y=read();scanf("%llu",&z);
143         if(Q==1)
144             query(x,y,z);
145         else
146             change(x,y,z);
147     }
148     return;
149 }
150 void Build(int x,int fa){
151     for(int i=0;i<ve[x].size();i++){
152         if(ve[x][i]==fa)continue;
153         t[ve[x][i]].fa=x;
154         Build(ve[x][i],x);
155     }
156     return;
157 }
158 int main(){
159     int i,j;
160     n=read();m=read();K=read();
161     for(i=1;i<=n;i++){
162         t[i].tp=read();
163         t[i].val=read();
164         f[i].f[1].set();
165         init(f[i].f[0],t[i].val,t[i].tp);
166         init(f[i].f[1],t[i].val,t[i].tp);
167     }
168     int u,v;
169     for(i=1;i<n;i++){
170         u=read();v=read();
171         ve[u].push_back(v); ve[v].push_back(u);
172     }
173     Build(1,0);
174     solve();
175     return 0;
176 }
原文地址:https://www.cnblogs.com/SilverNebula/p/6741841.html