• [Lydsy2017省队十连测]公路建设


    SOL:

     我们发现一棵生成树最多99条边,用线段树合并。

    #include<bits/stdc++.h>
    #define Mid (l+r>>1)
    #define ls no<<1,l,Mid
    #define rs no<<1|1,Mid+1,r
    #define N 110009
    using namespace std;
    struct Edge{
        int l,r,co;
    }e[N];
    int f[107];
    struct Node{
        int sum,a[107],to;
        void clear() {
            memset(a,0,sizeof a); sum=0; to=0;
        }
        int fa(int x){
            return f[x]==x?x:f[x]=fa(f[x]);
        }
        inline void join(int xx){
            static int u,v;
            u=fa(e[xx].l); v=fa(e[xx].r);
            if (u==v) return; 
            a[++to]=xx;
            f[u]=v;  sum+=e[xx].co;
        }
        void merge(Node X,Node& Y){
            static int ti,tj,op;
            clear();
            for (int i=1;i<107;i++) f[i]=i;
            ti=1; tj=1;
            while (X.a[ti]&&Y.a[tj]) 
                if (e[X.a[ti]].co<e[Y.a[tj]].co) join(X.a[ti++]);
                else join(Y.a[tj++]);
            while (X.a[ti]) join(X.a[ti++]);
            while (Y.a[tj]) join(Y.a[tj++]);
        }
    }t[N<<2],Ans;
    void build(int no,int l,int r){
        if (l==r) {
            t[no].sum=e[l].co;
            t[no].a[1]=l;   
            return;
        }
        build(no<<1,l,Mid); build(no<<1|1,Mid+1,r);
        t[no].merge(t[no<<1],t[no<<1|1]);
    }
    #define sight(x) ('0'<=x&&x<='9')
    inline void read(int &x){
        static char c;
        for (c=getchar();!sight(c);c=getchar());
        for (x=0;sight(c);c=getchar())x=x*10+c-48;
    }
    void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
    void que(int no,int l,int r,int L,int R){
        if (L<=l&&r<=R) {
            Ans.merge(Ans,t[no]); return;
        }
        if (L<=Mid) que(no<<1,l,Mid,L,R);
        if (R> Mid) que(no<<1|1,Mid+1,r,L,R);
    }
    int n,m,q,l,r;
    signed main () {
       read(n); read(m); read(q);
       for (int i=1;i<=m;i++) 
        read(e[i].l),read(e[i].r),read(e[i].co);
       build(1,1,m);
       while (q--) {
         read(l); read(r);
         Ans.clear();
         que(1,1,m,l,r);
         writeln(Ans.sum);
       }
       return 0;
    }
  • 相关阅读:
    Leveldb Advanced
    loadrunner生成随机数
    用strtok函数分割字符串
    loadrunner关联及web_reg_save_param方法浅析
    Linux中find用法
    在LoadRunner中从数组类型的参数随机取值的方法
    LoadRunner可以把关联取值当作检查点来使用
    Oracle特殊字符转义:&amp;和&#39;
    LoadRunner 11 error:Cannot initialize driver dll
    用SecureCRT在windows和CentOS间上传下载文件
  • 原文地址:https://www.cnblogs.com/rrsb/p/9126900.html
Copyright © 2020-2023  润新知