Submission #1363428

#TimeUsernameProblemLanguageResultExecution timeMemory
1363428liptonekWind Turbines (EGOI25_windturbines)C++20
100 / 100
356 ms61624 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAX_N=100005;

struct Edge
{
    int u,v;
    long long cost;
};

struct KRT
{
    int l,r;
    long long weight;
};

struct Triple
{
    int mn,mx;
    int id;
    long long w;
};

struct Query
{
    int l,r;
    int id;
};

int parent[2*MAX_N];

vector<KRT> nodes;
vector<Triple> points;
set<int>* subtrees[2*MAX_N];

long long bit[MAX_N];

bool compare_edges(const Edge& a, const Edge& b)
{
    return a.cost<b.cost;
}

int find(int i)
{
    if(parent[i]==i)
    {
        return i;
    }

    return parent[i]=find(parent[i]);
}

void dfs(int u, int n)
{
    if(u<n)
    {
        subtrees[u]=new set<int>();
        subtrees[u]->insert(u);

        return;
    }

    int idx=u-n;

    dfs(nodes[idx].l,n);
    dfs(nodes[idx].r,n);

    int l=nodes[idx].l;
    int r=nodes[idx].r;

    if(subtrees[l]->size()<subtrees[r]->size())
    {
        swap(l,r);
    }

    subtrees[u]=subtrees[l];

    for(int x : *subtrees[r])
    {
        auto it=subtrees[u]->lower_bound(x);

        if(it!=subtrees[u]->end())
        {
            points.push_back({x,*it,u,nodes[idx].weight});
        }

        if(it!=subtrees[u]->begin())
        {
            points.push_back({*prev(it),x,u,nodes[idx].weight});
        }
    }

    for(int x : *subtrees[r])
    {
        subtrees[u]->insert(x);
    }

    delete subtrees[r];
}

void update(int i, long long val, int n)
{
    for(i++; i<=n; i+=i & -i)
    {
        bit[i]+=val;
    }
}

long long query(int i)
{
    long long res=0;

    for(i++; i>0; i-=i & -i)
    {
        res+=bit[i];
    }

    return res;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int n,m,q;
    cin>>n>>m>>q;

    vector<Edge> edges(m);

    for(int i=0; i<m; i++)
    {
        cin>>edges[i].u>>edges[i].v>>edges[i].cost;
    }

    sort(edges.begin(),edges.end(),compare_edges);

    for(int i=0; i<2*n; i++)
    {
        parent[i]=i;
    }

    long long total=0;
    int ptr=n;

    for(int i=0; i<m; i++)
    {
        int ru=find(edges[i].u);
        int rv=find(edges[i].v);

        if(ru!=rv)
        {
            total+=edges[i].cost;

            nodes.push_back({ru,rv,edges[i].cost});

            parent[ru]=parent[rv]=ptr++;
        }
    }

    if(n>1)
    {
        dfs(ptr-1,n);
    }

    vector<Query> queries(q);

    for(int i=0; i<q; i++)
    {
        cin>>queries[i].l>>queries[i].r;

        queries[i].id=i;
    }

    sort(points.begin(),points.end(), [](const Triple& a, const Triple& b)
    {
        return a.mn>b.mn;
    });

    sort(queries.begin(),queries.end(), [](const Query& a, const Query& b)
    {
        return a.l>b.l;
    });

    vector<long long> ans(q);
    vector<int> best(ptr,n);

    int pid=0;

    for(int i=0; i<q; i++)
    {
        while(pid<(int)points.size() && points[pid].mn>=queries[i].l)
        {
            const auto& p=points[pid];

            if(p.mx<best[p.id])
            {
                if(best[p.id]<n)
                {
                    update(best[p.id],-p.w,n);
                }

                update(p.mx,p.w,n);

                best[p.id]=p.mx;
            }

            pid++;
        }

        ans[queries[i].id]=total-query(queries[i].r);
    }

    for(int i=0; i<q; i++)
    {
        cout<<ans[i]<<endl;
    }

    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...