码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5861 Road

时间:2016-08-19 20:26:04      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

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

这些天之间这条边都必须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;
}

 

HDU 5861 Road

标签:

原文地址:http://www.cnblogs.com/zufezzt/p/5788717.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!