zoukankan      html  css  js  c++  java
  • HYSBZ 2243(染色)

    题目链接:传送门

    题目大意:中文题,略

    题目思路:树链剖分,区间更新,区间查询。

    闲谈:      只想说这道题做的好苦逼。。去长春现场赛之前就没A,回来后又做了2天才A掉,蒟蒻太菜了

         这道题也没有想象中那么难,就是代码有点长。。

         在查询的时候注意判断端点交界处如果相同则答案-1。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <cctype>
    #include <queue>
    #include <string>
    #include <vector>
    #include <set>
    #include <map>
    #include <climits>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define fi first
    #define se second
    #define ping(x,y) ((x-y)*(x-y))
    #define mst(x,y) memset(x,y,sizeof(x))
    #define mcp(x,y) memcpy(x,y,sizeof(y))
    using namespace std;
    #define gamma 0.5772156649015328606065120
    #define MOD 1000000007
    #define inf 0x3f3f3f3f
    #define N 100005
    #define maxn 30010
    typedef pair<int,int> PII;
    typedef long long LL;
    LL read(){
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,k,sz,L,R;
    int a[N],mrk[N<<2];
    struct Seg{int l,r,v;}seg[N<<2];
    int son[N],siz[N],id[N],tid,posi[N];
    int top[N],fa[N],dep[N],head[N],hcnt;
    struct Node{int to,nxt;}node[N<<1];
    void dfs1(int u,int f,int deep){
        dep[u]=deep,fa[u]=f,siz[u]=1;
        for(int i=head[u];~i;i=node[i].nxt){
            int e=node[i].to;
            if(e==f)continue;
            dfs1(e,u,deep+1);
            siz[u]+=siz[e];
            if(!son[u]||siz[son[u]]<siz[e])
                son[u]=e;
        }
    }
    void dfs2(int u,int tp){
        top[u]=tp,id[u]=++tid,posi[tid]=u;
        if(!son[u])return;dfs2(son[u],tp);
        for(int i=head[u];~i;i=node[i].nxt){
            int e=node[i].to;
            if(!id[e])dfs2(e,e);
        }
    }
    void pushdown(int rt){
        seg[rt<<1].v=seg[rt<<1|1].v=1;
        seg[rt<<1].l=seg[rt<<1].r=mrk[rt];
        seg[rt<<1|1].l=seg[rt<<1|1].r=mrk[rt];
        mrk[rt<<1]=mrk[rt<<1|1]=mrk[rt];mrk[rt]=-1;
    }
    int query(int rt,int l,int r){
        if(L<=l&&r<=R)return seg[rt].v;
        int mid=l+r>>1,temp=0,t1=-1,t2=-1;
        if(~mrk[rt])pushdown(rt);
        if(L<=mid)t1=seg[rt<<1].r,temp+=query(lson);
        if(R>mid) t2=seg[rt<<1|1].l,temp+=query(rson);
        seg[rt].l=seg[rt<<1].l,seg[rt].r=seg[rt<<1|1].r;
        seg[rt].v=seg[rt<<1].v+seg[rt<<1|1].v-(seg[rt<<1].r==seg[rt<<1|1].l);
        temp-=(t1==t2&&t1!=-1);
        return temp;
    }
    void update(int rt,int l,int r,int v){
        if(L<=l&&r<=R){seg[rt].v=1,seg[rt].l=seg[rt].r=mrk[rt]=v;return;}
        int mid=l+r>>1;
        if(~mrk[rt])pushdown(rt);
        if(L<=mid)update(lson,v);
        if(R>mid) update(rson,v);
        seg[rt].l=seg[rt<<1].l,seg[rt].r=seg[rt<<1|1].r;
        seg[rt].v=seg[rt<<1].v+seg[rt<<1|1].v-(seg[rt<<1].r==seg[rt<<1|1].l);
    }
    int findp(int rt,int l,int r,int L){
        if(l==r)return seg[rt].l;
        int mid=l+r>>1,temp;
        if(~mrk[rt])pushdown(rt);
        if(L<=mid)return findp(lson,L);
        else return findp(rson,L);
    }
    void lca(int x,int y){
        int res=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            L=id[top[x]],R=id[x];
            res+=query(1,1,n);
            L=id[x];
            if(findp(1,1,n,id[top[x]])==findp(1,1,n,id[fa[top[x]]]))--res; ///看两端是否相同
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        L=id[x],R=id[y];
        res+=query(1,1,n);
        printf("%d
    ",res);
    }
    void change(int x,int y,int v){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            L=id[top[x]],R=id[x];
            update(1,1,n,v);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        L=id[x],R=id[y];
        update(1,1,n,v);
    }
    void build(int rt,int l,int r){
        if(l==r){seg[rt].l=seg[rt].r=a[posi[l]],seg[rt].v=1;return;}
        int mid=l+r>>1;
        build(lson);build(rson);
        seg[rt].v=seg[rt<<1].v+seg[rt<<1|1].v-(seg[rt<<1].r==seg[rt<<1|1].l);
        seg[rt].l=seg[rt<<1].l,seg[rt].r=seg[rt<<1|1].r;
    }
    int main(){
        int i,j,group,x,y,v;
        n=read(),m=read();mst(head,-1);mst(mrk,-1);
        for(i=1;i<=n;++i)a[i]=read();
        for(i=1;i<n;++i){
            x=read(),y=read();
            node[hcnt].to=y;node[hcnt].nxt=head[x],head[x]=hcnt++;
            node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;
        }
        dfs1(1,1,1);dfs2(1,1);build(1,1,n);
        char ch;
        while(m--){
            scanf(" %c",&ch);
            x=read(),y=read();
            if(ch=='Q') lca(x,y);
            else v=read(),change(x,y,v);
        }
        return 0;
    }
  • 相关阅读:
    mysql 主从服务器配置
    Linux命令
    Kali
    Python进阶
    性能测试工具
    sphinx搜索
    页面静态化
    PHP API接口
    线程的生命周期
    多线程的创建
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5924615.html
Copyright © 2011-2022 走看看