zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",temp);
                for(int &u:E[i])temp-=a[u];
            }
        }
        return 0;
    }
  • 相关阅读:
    闭包函数 (字符编码,文件处理,函数基础总结)
    函数参数详解
    文件处理及函数基础
    文件处理高级
    面向对象----反射
    正则表达式与re模块
    常用模块
    模块和包
    内置函数与匿名函数
    HDU
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5790177.html
Copyright © 2011-2022 走看看