zoukankan      html  css  js  c++  java
  • [BZOJ]4811: [Ynoi2017]由乃的OJ

     题解:   上一题的系列套路题  但是上一题 我们用n*log^3(n)水过了  这题6s明显是不可行的  需要优化一下复杂度  我们考虑线段树合并 维护每一位输入为0/1的时候输出 然后做区间合并  这样子平方转移依然是3个log的  我们想想二进制优化  让每一位对应unsigned long long每一二进制位然后把每次合并后的结果都用一个64位无符号整数存下来  这样就成2个log了  具体怎么合并 可以手推下

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=1e5+10;
    const double eps=1e-8;
    #define ll unsigned long long
    #define pii pair<ll,ll>
    using namespace std;
    struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    inline ll read()
    {
        ll ret=0;   char gc=getchar();
        while(gc<'0'||gc>'9') gc=getchar();
        while(gc>='0'&&gc<='9')   ret=ret*10+(gc-'0'),gc=getchar();
        return ret;
    }
    ll l0[MAXN<<2],l1[MAXN<<2],r0[MAXN<<2],r1[MAXN<<2];
    int opt[MAXN],n,m,k;
    ll a[MAXN],base;
    
    void up(int x){
        l0[x]=(l1[x<<1|1]&l0[x<<1])|((~l0[x<<1])&l0[x<<1|1]);
        l1[x]=(l1[x<<1]&l1[x<<1|1])|((~l1[x<<1])&l0[x<<1|1]);
        r0[x]=(r0[x<<1|1]&r1[x<<1])|((~r0[x<<1|1])&r0[x<<1]);
        r1[x]=(r1[x<<1|1]&r1[x<<1])|((~r1[x<<1|1])&r0[x<<1]);
    }
    
    void Opt1(int x,ll y){
        l0[x]=r0[x]=0;
        l1[x]=r1[x]=y;
    }
    
    void Opt2(int x,ll y){
        l0[x]=r0[x]=y;
        l1[x]=r1[x]=base;
    }
    
    void Opt3(int x,ll y){
        l0[x]=r0[x]=y;
        l1[x]=r1[x]=(base^y);
    }
    
    int tp[MAXN],p[MAXN],fp[MAXN],cnt;
    void built(int x,int l,int r){
        if(l==r){
    	if(opt[fp[l]]==1)Opt1(x,a[fp[l]]);
    	else if(opt[fp[l]]==2)Opt2(x,a[fp[l]]);
    	else Opt3(x,a[fp[l]]);
    	return ;
        }
        int mid=(l+r)>>1;
        built(x<<1,l,mid);
        built(x<<1|1,mid+1,r);
        up(x);
    }
    
    void update(int x,int l,int r,int t){
        if(l==r){
    	if(opt[fp[l]]==1)Opt1(x,a[fp[l]]);
    	else if(opt[fp[l]]==2)Opt2(x,a[fp[l]]);
    	else Opt3(x,a[fp[l]]);
    	return ;
        }
        int mid=(l+r)>>1;
        if(t<=mid)update(x<<1,l,mid,t);
        else update(x<<1|1,mid+1,r,t);
        up(x);
    }
    
    pii ans;
    void query1(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
    	ans.first=(ans.first&l1[x])|(~ans.first&l0[x]);
    	ans.second=(ans.second&l1[x])|(~ans.second&l0[x]);
    	return ;
        }
        int mid=(l+r)>>1;
        if(ql<=mid)query1(x<<1,l,mid,ql,qr);
        if(qr>mid)query1(x<<1|1,mid+1,r,ql,qr);
    }
    
    void query2(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
    	ans.first=(ans.first&r1[x])|(~ans.first&r0[x]);
    	ans.second=(ans.second&r1[x])|(~ans.second&r0[x]);
    	return ;
        }
        int mid=(l+r)>>1;
        if(qr>mid)query2(x<<1|1,mid+1,r,ql,qr);
        if(ql<=mid)query2(x<<1,l,mid,ql,qr);
    }
    
    int son[MAXN],num[MAXN],dep[MAXN],fa[MAXN];
    void dfs1(int x,int pre,int deep){
        fa[x]=pre;num[x]=1;dep[x]=deep+1;
        link(x)if(j->t!=pre){
    	dfs1(j->t,x,deep+1);
    	num[x]+=num[j->t];
    	if(son[x]==-1||num[son[x]]<num[j->t])son[x]=j->t;
        }
    }
    
    void dfs2(int x,int td){
        tp[x]=td;p[x]=++cnt;fp[p[x]]=x;
        if(son[x]!=-1)dfs2(son[x],td);
        link(x)if(j->t!=son[x]&&j->t!=fa[x])dfs2(j->t,j->t);
    }
    
    pii st[MAXN];int tot;
    
    void solve(int u,int v,ll z){
        int uu=tp[u];int vv=tp[v];
        ans.first=0;ans.second=base;
        tot=0;
        while(uu!=vv){
    	if(dep[uu]>dep[vv])query2(1,1,n,p[uu],p[u]),u=fa[uu],uu=tp[u];
    	else st[++tot]=mp(p[vv],p[v]),v=fa[vv],vv=tp[v];
        }
        if(dep[u]>dep[v])query2(1,1,n,p[v],p[u]);
        else query1(1,1,n,p[u],p[v]);
        dec(i,tot,1)query1(1,1,n,st[i].first,st[i].second);
        ll ans1=0;ll maxx=0;
        for(int i=k-1;i>=0;i--){
    	int t1=((ans.first>>i)&1);
    	int t2=((ans.second>>i)&1);
    	if(t1&&t2)maxx+=(1ll<<i);
    	else if(t1&&!t2)maxx+=(1ll<<i);
    	else if(!t1&&t2){
    	    if(ans1+(1ll<<i)<=z)ans1+=(1ll<<i),maxx+=(1ll<<i);
    	}
        }
        printf("%llu
    ",maxx);
    }
    
    
    int main(){
        n=read();m=read();k=read();
        for(int i=0;i<k;i++)base|=(1ULL<<i);
        inc(i,1,n)son[i]=-1;
        inc(i,1,n)opt[i]=read(),a[i]=read();
        int u,v;
        inc(i,2,n)u=read(),v=read(),add(u,v),add(v,u);
        dfs1(1,0,0);dfs2(1,1);built(1,1,n);
        int x,y,op;ll z;
        while(m--){
    	op=read();x=read();y=read();z=read();
    	if(op==1)solve(x,y,z);
    	else opt[x]=y,a[x]=z,update(1,1,n,p[x]);
        }
        return 0;
    }
    

      

    4811: [Ynoi2017]由乃的OJ

    Time Limit: 6 Sec  Memory Limit: 256 MB
    Submit: 740  Solved: 271
    [Submit][Status][Discuss]

    Description

    由乃正在做她的OJ。现在她在处理OJ上的用户排名问题。OJ上注册了n个用户,编号为1~",一开始他们按照编号
    排名。由乃会按照心情对这些用户做以下四种操作,修改用户的排名和编号:然而由乃心情非常不好,因为Deus天
    天问她题。。。因为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所以她还是只能找你帮她做了。。。
    给你一个有n个点的树,每个点的包括一个位运算opt和一个权值x,位运算有&,l,^三种,分别用1,2,3表示。
    每次询问包含三个数x,y,z,初始选定一个数v。然后v依次经过从x到y的所有节点,每经过一个点i,v就变成v opti
     xi,所以他想问你,最后到y时,希望得到的值尽可能大,求最大值?给定的初始值v必须是在[0,z]之间。每次修
    改包含三个数x,y,z,意思是把x点的操作修改为y,数值改为z

    Input

    第一行三个数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意义如题所述
    0 <= n , m <= 100000 , k <= 64

    Output

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

    Sample Input

    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

    Sample Output

    7
    1
    5

    HINT

     

    Source

  • 相关阅读:
    Ubuntu配置sublime text 3的c编译环境
    ORA-01078错误举例:SID的大写和小写错误
    linux下多进程的文件拷贝与进程相关的一些基础知识
    ASM(四) 利用Method 组件动态注入方法逻辑
    基于Redis的三种分布式爬虫策略
    Go语言并发编程总结
    POJ2406 Power Strings 【KMP】
    nyoj 会场安排问题
    Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    Java的String、StringBuffer和StringBuilder的区别
  • 原文地址:https://www.cnblogs.com/wang9897/p/10363462.html
Copyright © 2011-2022 走看看