zoukankan      html  css  js  c++  java
  • 洛谷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 }
  • 相关阅读:
    javascript 对象属性的添加,删除,json对象和字符串转换方法等
    利用jquery.form.js实现将form提交转为ajax方式提交的方法(带上传的表单提交)
    js封装的一行半显示省略号。(字数自由控制)
    jq和js中click 事件的几种方式总结和click事件的累加问题解决办法
    jquery $(document).ready() 与js原生的window.onload的区别总结
    jquery中attr和prop的区别
    织梦文档按权重排序
    织梦channelartlist标签内使用currentstyle
    dedecms无法下载远程jpeg图片 织梦不能提取文章内容中的jpeg图片生成缩略图
    织梦dedecms去除友情链接中的li和span
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6741841.html
Copyright © 2011-2022 走看看