hdu5861(Road)

题目链接:传送门

题目大意:有n个点 组成n-1段,每一段开着的时候都有花费Vi,有m组要求,对于每组要求 [x,y]之间可达,对于每一段你有一次开关的机会(最初都是关闭的)

     问怎样安排段落得开闭时间使花费最小,输出每天的花费

题目思路:网上题解很多是线段树,但感觉不需要线段树,只需要统计每个点第一次出现的时间(开)和最后一次出现的时间(关)然后以时间为循环扫一遍即可。

     于是自己先写了一发,全程用vector模拟,估计是插入和删除操作过多,以及vector本身速度慢,不幸TLE。实际上我模拟的操作也就是想对于每一次

     询问,将未覆盖的点(之前还没出现过)标记为已覆盖,加入到相应vector中。而关键在于怎样快速的处理一段点是否被覆盖?

     我是用vecotr保存 1~n然后只要当前被覆盖,将覆盖过的点删除,剩下没覆盖的点。而且每次询问的查找是用二分,应该很快了。结果还是Tle

     第二种方法(参考网上大牛),用并查集。fp[i]表示 i~第一个未覆盖的点,这样对于询问来说,只需要常数级的操作就能判断更新出来。实在太高明了%%%

附上TLE代码

#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 200005
#define maxn 100005
typedef pair<int,int> PII;
typedef long long LL;

int n,m,k,T;
int a[N];
vector<int>V[N],E[N],K,er;
struct Node{
    int x,y;
}node[N];
int ans[N];
int main(){
    //freopen("in.txt","r",stdin);
    int i,j,x,y,v,l;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(i=1;i<n;++i)scanf("%d",&a[i]);
        K.clear();
        for(i=1;i<=n;++i)K.push_back(i);
        for(i=1;i<=m;++i){
            V[i].clear();E[i].clear();
            scanf("%d%d",&node[i].x,&node[i].y);
            if(node[i].x>node[i].y){
                node[i].x^=node[i].y^=node[i].x^=node[i].y;
            }
            node[i].y--;
        }
        vector<int>::iterator it;
        for(i=1;i<=m;++i){
            int pos=lower_bound(K.begin(),K.end(),node[i].x)-K.begin();
            it=K.begin()+pos;
            int cnt=0;
            while(pos<K.size()&&node[i].y>=K[pos]){
                V[i].push_back(K[pos++]);
                ++cnt;
            }
            for(;it!=K.end()&&cnt;--cnt){
                K.erase(it);
            }
        }
        K.clear();
        for(i=1;i<=n;++i)K.push_back(i);
        for(i=m;i>=1;--i){
            int pos=lower_bound(K.begin(),K.end(),node[i].x)-K.begin();
            it=K.begin()+pos;
            int cnt=0;
            while(pos<K.size()&&node[i].y>=K[pos]){
                E[i].push_back(K[pos++]);
                ++cnt;
            }
            for(;it!=K.end()&&cnt;--cnt)
                K.erase(it);
        }
        int temp=0;
        for(i=1;i<=m;++i){
            for(int &u:V[i])
                temp+=a[u];
            for(int &u:E[i-1])
                temp-=a[u];
            printf("%d\n",temp);
        }
    }
    return 0;
}

AC代码 1622ms

#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 200005
#define maxn 100005
typedef pair<int,int> PII;
typedef long long LL;

int n,m,k,T;
int a[N];
vector<int>V[N],E[N],K,er;
struct Node{
    int x,y;
}node[N];
int ans[N],fp[N];
int findp(int x){return fp[x]==x?x:fp[x]=findp(fp[x]);}
int main(){
    //freopen("in.txt","r",stdin);
    int i,j,x,y,v,l;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(i=1;i<n;++i)scanf("%d",&a[i]);
        for(i=1;i<=m;++i){
            V[i].clear();E[i].clear();
            scanf("%d%d",&x,&y);
            if(x>y)x^=y^=x^=y;
            y--;
            node[i].x=x;node[i].y=y;
        }
        for(i=1;i<=n;++i)fp[i]=i;
        for(i=1;i<=m;++i){
            while(true){
                x=findp(node[i].x);
                y=node[i].y;
                if(x>y)break;
                fp[x]=x+1;
                V[i].push_back(x);
            }
        }
        for(i=1;i<=n;++i)fp[i]=i;
        for(i=m;i>=1;--i){
            while(true){
                x=findp(node[i].x);
                y=node[i].y;
                if(x>y)break;
                fp[x]=x+1;
                E[i].push_back(x);
            }
        }
        int temp=0;
        for(i=1;i<=m;++i){
            for(int &u:V[i])temp+=a[u];
            printf("%d\n",temp);
            for(int &u:E[i])temp-=a[u];
        }
    }
    return 0;
}
时间: 2024-10-09 10:32:57

hdu5861(Road)的相关文章

洛谷P2242 公路维修问题(Road)

题目描述 在一个夜黑风高,下着暴风雨的夜晚,farmer John的牛棚的屋顶.门被吹飞了. 好在许多牛正在度假,所以牛棚没有住满. 牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜. 有些牛棚里有牛,有些没有. 所有的牛棚有相同的宽度. 自门遗失以后,farmer John必须尽快在牛棚之前竖立起新的木板. 他的新木材供应商将会供应他任何他想要的长度,但是吝啬的供应商只能提供有限数目的木板. farmer John想将他购买的木板总长度减到最少. 给出:可能买到的木板最大的数目M(1<= M<

HDU 1598 find the most comfortable road (最小生成树) &gt;&gt;

Problem Description XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的"舒适度"有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ), 但XX星人对时间却没那么多要求.要你找出一条城市间的最舒适的路径.(

HDU-4081 Qin Shi Huang&#39;s National Road System(最小生成树)

今天比赛AC的一道最小生成树的题目 , 学到了不少东西 . 最小生成树的模板很简单,最简洁好写的还是lrj紫书上的代码 .利用并查集加速算法 . 该题的不同之处在于它选择任意一条路修成"魔法"道路 , 然后其他路的权值之和还要是最小的一棵次小生成树,并且求魔法道路两端点值之和除以其他路径长之和的最大值 . 显然该题的难点在于枚举两个端点之后怎么快速的求出次小生成树权值之和 .  枚举两个端点之后的复杂度已经是O(n^2),所以要想出一个快速的方法 . 受紫书上例题uva 1151 (传

HDU 4081 Qin Shi Huang&#39;s National Road System(prim)

Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5153    Accepted Submission(s): 1795 Problem Description During the Warring States Period of ancient China(4

UVA 1494 - Qin Shi Huang&#39;s National Road System(MST)

UVA 1494 - Qin Shi Huang's National Road System 题目链接 题意:秦始皇修路,要求所有道路连通,现在道士徐福可以用法术修一条路,问现在用法术修路的两边的人口数A,除以总修路长度B的最大值A/B是多少 思路:先求出最小生成树,然后利用dfs找出每两点之间的最大权的边的权值,然后在枚举哪两个城市需要法术修路,这样就可以记录下答案最大值 代码: #include <cstdio> #include <cstring> #include <

C#.Net 设计模式学习笔记之创建型 (一)

1.抽象工厂(Abstract Factory)模式 常规的对象创建方法: //创建一个Road对象 Road road =new Road(); new 的问题: 实现依赖,不能应对"具体实例化类型"的变化. 解决思路: 封装变化点-----哪里变化,封装哪里 潜台词: 如果没有变化,当然不需要额外的封装! 工厂模式的缘起 变化点在"对象创建",因此就封装"对象创建" 面向接口编程----依赖接口,而非依赖实现 最简单的解决方法: class 

小白日记3:kali渗透测试之被动信息收集(二)-dig、whios、dnsenum、fierce

一.DIG linux下查询域名解析有两种选择,nslookup或者dig.Dig(Domain Information Groper)是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,MX记录等相关信息的工具. <span style="font-size:18px;">[email protected]:~# dig -h Usage: dig [@global-server] [domain] [q-type] [q-class] {q-opt} {glo

uva 757 Gone Fishing (贪心)

uva 757 Gone Fishing John is going on a fishing trip. He has h hours available ( ), and there are n lakes in the area ( ) all reachable along a single, one-way road. John starts at lake 1, but he can finish at any lake he wants. He can only travel fr

Uva 10815-Andy&#39;s First Dictionary(串)

Problem B: Andy's First Dictionary Time limit: 3 seconds Andy, 8, has a dream - he wants to produce his very own dictionary. This is not an easy task for him, as the number of words that he knows is, well, not quite enough. Instead of thinking up all