zoukankan      html  css  js  c++  java
  • [BZOJ]2908: 又是nand

     题解:  LCT死于卡常....迫不得已写了树剖+线段树  思路很简单   按位分解 对于每一位  考虑这条路径上从右往左第一个0出现的位置   然后判断这一位经过这条路径后是0还是1  统计每一位贡献即可

    #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 pii pair<int,int>
    #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 long long
    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++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    int sum[MAXN<<2][33];
    ll a[MAXN];
    int k,n,m,fp[MAXN],p[MAXN];
    
    void up(int x){
        inc(i,0,k-1)sum[x][i]=sum[x<<1][i]+sum[x<<1|1][i];
    }
    
    void built(int x,int l,int r){
        if(l==r){
    	inc(i,0,k-1)sum[x][i]=((a[fp[l]]>>i)&1);
    	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,int key){
        if(l==r){
    	inc(i,0,k-1)sum[x][i]=((key>>i)&1);
    	return ;
        }
        int mid=(l+r)>>1;
        if(t<=mid)update(x<<1,l,mid,t,key);
        else update(x<<1|1,mid+1,r,t,key);
        up(x);
    }
    
    int ans[33];
    void query1(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
    	inc(i,0,k-1)ans[i]+=sum[x][i];
    	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);
    }
    
    int pos;
    void query2(int x,int l,int r,int ql,int qr,int id){
        if(pos)return ;
        if(ql<=l&&r<=qr){
    	if(sum[x][id]==r-l+1){return ;}
    	if(l==r){pos=l;return ;}
        }
        int mid=(l+r)>>1;
        if(qr>mid)query2(x<<1|1,mid+1,r,ql,qr,id);
        if(ql<=mid)query2(x<<1,l,mid,ql,qr,id);
    }
    
    void query3(int x,int l,int r,int ql,int qr,int id){
        if(pos)return ;
        if(ql<=l&&r<=qr){
    	if(sum[x][id]==r-l+1){return ;}
    	if(l==r){pos=l;return ;}
        }
        int mid=(l+r)>>1;
        if(ql<=mid)query3(x<<1,l,mid,ql,qr,id);
        if(qr>mid)query3(x<<1|1,mid+1,r,ql,qr,id);
    }
    
    
    int fa[MAXN],dep[MAXN],num[MAXN],son[MAXN];
    void dfs1(int x,int pre,int deep){
        fa[x]=pre;dep[x]=deep+1;num[x]=1;
        link(x){
    	if(j->t==pre)continue;
    	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;
        }
    }
    
    int tp[MAXN],cnt;
    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!=fa[x]&&j->t!=son[x])dfs2(j->t,j->t);
    }
    
    pii st[MAXN],ed[MAXN];int tot1,tot2;
    int vis[33];
    
    int Lca(int x,int y){
        int xx=tp[x];int yy=tp[y];
        while(xx!=yy){
    	if(dep[xx]<dep[yy])swap(xx,yy),swap(x,y);
    	x=fa[xx];xx=tp[x];
        }
        if(dep[x]>dep[y])swap(x,y);
        return x;
    }
    
    void solve(int u,int v){
        int y=v,x=u;
        inc(i,0,k-1)vis[i]=0;
        int uu=tp[u];int vv=tp[v];tot2=tot1=0;
        while(uu!=vv){
    	if(dep[uu]>dep[vv]){ed[++tot2]=mp(p[uu],p[u]);u=fa[uu];uu=tp[u];}
    	else {st[++tot1]=mp(p[vv],p[v]);v=fa[vv];vv=tp[v];}
        }
        if(dep[u]>dep[v])ed[++tot2]=mp(p[v],p[u]);
        else st[++tot1]=mp(p[u],p[v]);
        inc(i,1,tot1){
    	inc(j,0,k-1)ans[j]=0;
    	query1(1,1,n,st[i].first,st[i].second);
    	inc(j,0,k-1){
    	    if(vis[j])continue;
    	    if(ans[j]==st[i].second-st[i].first+1)continue;
    	    pos=0;
    	    query2(1,1,n,st[i].first,st[i].second,j);
    	    vis[j]=pos;
    	}
        }
        dec(i,tot2,1){
    	inc(j,0,k-1)ans[j]=0;
    	query1(1,1,n,ed[i].first,ed[i].second);
    	inc(j,0,k-1){
    	    if(vis[j])continue;
    	    if(ans[j]==ed[i].second-ed[i].first+1)continue;
    	    pos=0;
    	    query3(1,1,n,ed[i].first,ed[i].second,j);
    	    vis[j]=pos;
    	}
        }
        ll Sum=0;
        inc(i,0,k-1){
    	if(vis[i])u=fp[vis[i]];
    	else u=x; 
    	int lca=Lca(u,y);
    	int t=dep[u]+dep[y]-2*dep[lca]+1;
    	if((t&1))Sum+=(1ll<<i);
        }
        printf("%lld
    ",Sum);
    }
    
    int main(){
        n=read();m=read();k=read();
        inc(i,1,n)son[i]=-1,a[i]=read();
        int u,v;
        inc(i,2,n)u=read(),v=read(),add(u,v),add(v,u);
        char str[21];
        dfs1(1,0,0);dfs2(1,1);
        built(1,1,n);
        while(m--){
    	scanf("%s",str);u=read(),v=read();
    	if(str[0]=='R')update(1,1,n,p[u],v);
    	else solve(u,v);
        }
        return 0;
    }
    

      

    2908: 又是nand

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 557  Solved: 183
    [Submit][Status][Discuss]

    Description

    首先知道A nand B=not(A and B) (运算操作限制了数位位数为K)比如2 nand 3,K=3,则2 nand 3=not (2 and 3)=not 2=5。
    给出一棵树,树上每个点都有点权,定义树上从a到b的费用为0与路径上的点的权值顺次nand的结果,例如:从2号点到5号点顺次经过2->3->5,权值分别为5、7、2,K=3,那么最终结果为0 nand 5 nand 7 nand 2=7 nand 7 nand 2=0 nand 2=7,现在这棵树需要支持以下操作。
    ①    Replace a b:将点a(1≤a≤N)的权值改为b。
    ②    Query a b:输出点a到点b的费用。
    请众神给出一个程序支持这些操作。

    Input

    第一行N,M,K,树的节点数量、总操作个数和运算位数。
    接下来一行N个数字,依次表示节点i的权值。
    接下来N-1行,每行两个数字a,b(1≤a,b≤N)表示a,b间有一条树边。
    接下来M行,每行一个操作,为以上2类操作之一。
    N、M≤100000,K≤32

    Output

    对于操作②每个输出一行,如题目所述。

    Sample Input

    3 3 3
    2 7 3
    1 2
    2 3
    Query 2 3
    Replace 1 3
    Query 1 1

    Sample Output

    4
    7
  • 相关阅读:
    ICONS-图标库
    图形资源
    vue项目中,如果修改了组件名称,vscode编辑器会在引入修改组件的名字处提示红色波浪线 The file is in the program because:Imported via xxx Root file specified for compilation .
    接口在dev环境报跨域问题(has been blocked by CORS policy:Response to preflight request doesn't pass access control check:No 'Access-Control-Allow-Origin' header ispresent on the requested resource.),qa环境正常
    阿里云occ的图片文件URL用浏览器直接打开无法访问,提示This XML file does noe appear to have any style information associated with it. The document tree is shown below.
    vue 项目使用element ui 中tree组件 check-strictly 用法(父子不互相关联的反显情况)
    高德地图进行线路规划绘制标记点操作(vue)
    vue中实现拖拽调整顺序功能
    2021-01-22 浏览器相关知识
    2021-01-22 js 相关知识点
  • 原文地址:https://www.cnblogs.com/wang9897/p/10362929.html
Copyright © 2011-2022 走看看