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\n",quary(i,1,m,1));
    }
    return 0;
}

 

posted @ 2016-08-19 18:37  Fighting_Heart  阅读(130)  评论(0编辑  收藏  举报