zoukankan      html  css  js  c++  java
  • HDU 5861 Road

    首先要计算出每一条路最早开始的那一天,然后最晚结束的那一天。

    这些天之间这条边都必须$open$,然后就变成一个线段树区间$+val$的问题了,最后询问一个每个点的$val$是多少。

    注意:数据中有$ai>bi$的情况。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    #include<ctime>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0);
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    
    const int maxn=200010;
    int T,n,m,w[maxn];
    struct X{ int u,v; }p[maxn];
    int L[maxn],R[maxn];
    int s[4*maxn];
    
    void build(int l,int r,int rt)
    {
        s[rt]=0;
        if(l==r) return;
        int m=(l+r)/2;
        build(l,m,2*rt);
        build(m+1,r,2*rt+1);
    }
    
    void update(int L,int R,int x,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            if(s[rt]==0) s[rt]=x;
            return;
        }
    
        if(s[rt]!=0)
        {
            if(s[2*rt]==0) s[2*rt]=s[rt];
            if(s[2*rt+1]==0) s[2*rt+1]=s[rt];
        }
    
        int m=(l+r)/2;
        if(L<=m) update(L,R,x,l,m,2*rt);
        if(R>m) update(L,R,x,m+1,r,2*rt+1);
    }
    
    int get(int pos,int l,int r,int rt)
    {
        if(l==r) { return s[rt]; }
    
        if(s[2*rt]==0) s[2*rt]=s[rt];
        if(s[2*rt+1]==0) s[2*rt+1]=s[rt];
    
        int m =(l+r)/2;
        if(l<=pos&&pos<=m) return get(pos,l,m,2*rt);
        else return get(pos,m+1,r,2*rt+1);
    }
    
    
    void ADD(int L,int R,int x,int l,int r,int rt)
    {
        if(L<=l&&r<=R) { s[rt]+=x; return; }
        int m=(l+r)/2;
        if(L<=m) ADD(L,R,x,l,m,2*rt);
        if(R>m) ADD(L,R,x,m+1,r,2*rt+1);
    }
    
    int quary(int pos,int l,int r,int rt)
    {
        if(l==r) return s[rt];
    
        if(s[rt]!=0)
        {
            s[2*rt]+=s[rt];
            s[2*rt+1]+=s[rt];
            s[rt]=0;
        }
    
        int m =(l+r)/2;
        if(l<=pos&&pos<=m) return quary(pos,l,m,2*rt);
        else return quary(pos,m+1,r,2*rt+1);
    
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=1; i<=n-1; i++) scanf("%d",&w[i]);
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d",&p[i].u,&p[i].v);
                if(p[i].v<p[i].u) swap(p[i].v,p[i].u);
            }
            build(1,n,1);
            for(int i=1; i<=m; i++) update(p[i].u,p[i].v-1,i,1,n,1);
            for(int i=1; i<=n-1; i++) L[i]=get(i,1,n,1);
    
            build(1,n,1);
            for(int i=m; i>=1; i--) { update(p[i].u,p[i].v-1,i,1,n,1); }
            for(int i=1; i<=n-1; i++) R[i]=get(i,1,n,1);
    
            build(1,m,1);
            for(int i=1;i<=n-1;i++)
            {
                if(L[i]==0||R[i]==0) continue;
                ADD(L[i],R[i],w[i],1,m,1);
            }
            for(int i=1;i<=m;i++) printf("%d
    ",quary(i,1,m,1));
        }
        return 0;
    }
  • 相关阅读:
    Debian 添加用户
    如何让安卓手机访问内网服务器?
    数据库权限
    CentOs
    批量导入sql文件。
    使用Navicat Premium连接mysql数据库
    git 合包
    linux 下文件打包
    git 分支管理
    gcc8.2安装
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5788717.html
Copyright © 2011-2022 走看看