zoukankan      html  css  js  c++  java
  • hdu5893 List wants to travel(树链剖分+线段树)

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 270    Accepted Submission(s): 47


    Problem Description
    A boy named List who is perfect in English. Now he wants to travel and he is making a plan. But the cost of living in same citie always changes. Now he wants to know how many different kinds of continuous same cost he has to pay for living between two cities. Can you help him? (He is so lazy to do this by himself.)
     

    Input
    There are multiple cases. The first line contains two positive numbers N and M(N (N<=40000) where N is the amount of cities and M (M<=50000)) is the amount of operations.Then N-1 lines where each line have 3 integers a b and c, representing that there is a bidirectionoal road between city a and city b, and the cost is c.(a != b and c <= 100000). Then there are M lines of operation. For example, "Change a b c" means changing all the costs of the road which are passed by him when he travels from city a to city b to c. "Query a b" means he wants you to tell him how many different kinds of continuous same cost he has to pay traveling from city a to city b.(if a == b, the cost is 0).
     

    Output
    He insure you that there is exactly one route between every two different cities.
     

    Sample Input
    9 3 1 2 2 2 3 1 1 7 2 1 4 2 3 5 2 3 6 1 5 8 2 5 9 3 Query 1 8 Change 2 6 3 Query 1 6
     

    Sample Output
    3 2

    题意:和bzoj2243题目几乎一样,区别在于bzoj颜色在点上,这题颜色在边上。

    思路:先树链剖分,然后用线段树维护num(不同颜色的段数),cl(线段左端点的颜色),cr(线段右端点的颜色),然后因为处理的是线段,所以这里要把线段上的颜色当成这条线段连接的两个点深度更大的点的颜色,然后就和bzoj2243一样了。比赛的时候记得这题,但是因为是线段上的颜色,就不会了,亥,还是太弱了。。

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<string>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    #define lson th<<1
    #define rson th<<1|1
    typedef long long ll;
    typedef long double ldb;
    #define inf 999999999
    #define pi acos(-1.0)
    #define maxn 40010
    #define maxm 50050
    
    struct edge{
        int to,next,len;
    }e[2*maxm];
    int pos,tot,Lc,Rc;
    int top[maxn],son[maxn],fa[maxn],dep[maxn],num[maxn],p[maxn],a[maxn],c[maxn],first[maxn];
    void dfs1(int u,int pre,int deep)
    {
        int i,j,v;
        dep[u]=deep;
        fa[u]=pre;
        num[u]=1;
        for(i=first[u];i!=-1;i=e[i].next){
            v=e[i].to;
            if(v==pre)continue;
            a[v]=e[i].len;
            dfs1(v,u,deep+1);
            num[u]+=num[v];
            if(son[u]==-1 || num[son[u] ]<num[v]){
                son[u]=v;
            }
        }
    }
    
    void dfs2(int u,int tp)
    {
        int i,j,v;
        top[u]=tp;
        if(son[u]!=-1){
            p[u]=++pos;
            c[pos]=a[u];
            dfs2(son[u],tp);
        }
        else{
            p[u]=++pos;
            c[pos]=a[u];
            return;
        }
        for(i=first[u];i!=-1;i=e[i].next){
            v=e[i].to;
            if(v==son[u] || v==fa[u])continue;
            dfs2(v,v);
        }
    }
    
    
    struct node{
        int l,r,num,cl,cr,flag;
    }b[4*maxn];
    
    void pushup(int th)
    {
        b[th].cl=b[lson].cl;
        b[th].cr=b[rson].cr;
        b[th].num=b[lson].num+b[rson].num;
        if(b[lson].cr==b[rson].cl)b[th].num--;
    }
    
    void pushdown(int th)
    {
        if(b[th].flag==1){
            b[lson].flag=b[rson].flag=1;
            b[lson].cl=b[lson].cr=b[rson].cl=b[rson].cr=b[th].cl;
            b[lson].num=b[rson].num=1;
            b[th].flag=-1;
        }
    }
    
    void build(int l,int r,int th)
    {
        int mid;
        b[th].l=l;b[th].r=r;
        b[th].flag=-1;
        if(l==r){
            b[th].cl=b[th].cr=c[l];
            b[th].num=1;
            return;
        }
        mid=(b[th].l+b[th].r)/2;
        build(l,mid,lson);
        build(mid+1,r,rson);
        pushup(th);
    }
    
    void update(int l,int r,int color,int th)
    {
        int mid;
        if(b[th].l==l && b[th].r==r){
            b[th].num=1;
            b[th].flag=1;
            b[th].cl=b[th].cr=color;
            return;
        }
        pushdown(th);
        mid=(b[th].l+b[th].r)/2;
        if(r<=mid)update(l,r,color,lson);
        else if(l>mid)update(l,r,color,rson);
        else{
            update(l,mid,color,lson);
            update(mid+1,r,color,rson);
        }
        pushup(th);
    }
    
    int question(int l,int r,int th,int L,int R)
    {
        int mid,num;
        if(b[th].l==L)Lc=b[th].cl;
        if(b[th].r==R)Rc=b[th].cr;
        if(b[th].l==l && b[th].r==r){
            return b[th].num;
        }
        pushdown(th);
        mid=(b[th].l+b[th].r)/2;
        if(r<=mid)return question(l,r,lson,L,R);
        else if(l>mid)return question(l,r,rson,L,R);
        else{
            num=question(l,mid,lson,L,R)+question(mid+1,r,rson,L,R);
            if(b[lson].cr==b[rson].cl)num--;
            return num;
        }
    }
    
    int solve(int u,int v)
    {
        int f1,f2;
        f1=top[u];f2=top[v];
        int num=0,pre1,pre2;
        pre1=pre2=-1;
        while(f1!=f2){
            if(dep[f1]<dep[f2]){
                swap(pre1,pre2);swap(f1,f2);swap(u,v);
            }
            num+=question(p[f1],p[u],1,p[f1],p[u]);
            if(pre1==Rc)num--;
            pre1=Lc;
            u=fa[f1];
            f1=top[u];
        }
        if(u!=v){
            if(dep[u]<dep[v]){
                swap(pre1,pre2);swap(u,v);
            }
            num+=question(p[son[v]],p[u],1,p[son[v]],p[u]);
            if(pre1!=-1 && Rc==pre1)num--;
            if(pre2!=-1 && Lc==pre2)num--;
        }
        else if(pre1==pre2)num--;
        return num;
    }
    
    void gengxin(int u,int v,int value)
    {
        int f1,f2;
        f1=top[u];f2=top[v];
        while(f1!=f2){
            if(dep[f1]<dep[f2]){
                swap(f1,f2);swap(u,v);
            }
            update(p[f1],p[u],value,1);
            u=fa[f1];
            f1=top[u];
        }
        if(dep[u]<dep[v]){
            swap(u,v);
        }
        if(u!=v){
            update(p[son[v]],p[u],value,1);
        }
    }
    void add(int u,int v,int len)
    {
        tot++;
        e[tot].next=first[u];e[tot].to=v;e[tot].len=len;
        first[u]=tot;
    }
    int main()
    {
        int i,j,n,m,u,v,f,g,h,w;
        char s[10];
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(first,-1,sizeof(first));
            memset(son,-1,sizeof(son));
            pos=0;tot=0;
            for(i=1;i<=n-1;i++){
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);add(v,u,w);
            }
            dfs1(1,0,1);
            dfs2(1,1);
    
            build(1,pos,1);
            for(i=1;i<=m;i++){
                scanf("%s",s);
                if(s[0]=='Q'){
                    scanf("%d%d",&f,&g);
                    printf("%d
    ",solve(f,g));
                }
                else{
                    scanf("%d%d%d",&f,&g,&h);
                    gengxin(f,g,h);
                }
            }
    
        }
        return 0;
    }
    


  • 相关阅读:
    WinowsXP 任务栏无法显示当前运行程序图标
    日志记录组件[Log4net]详细介绍(转)
    桌面上的IE图标变成了快捷方式那种图标 怎么还原回来
    面试必须要知道的SQL语法,语句(转载)
    兼容 火狐 IE 的JS时间控件 任意格式 年月日时分秒
    Nagios远程监控软件的安装与配置详解(1)
    linux集群 负载均衡实验笔记
    PHPB2B 模板 标签
    PHP 去除 HTML 回车 换行 空格
    OpenX参考网址
  • 原文地址:https://www.cnblogs.com/herumw/p/9464474.html
Copyright © 2011-2022 走看看