codeforces 787d[补]

本文介绍了一个结合线段树与最短路径算法的复杂问题解决方案,通过对点和区间建立特殊映射,有效减少了边的数量,从而将时间复杂度优化到O(nlog²n),适用于大规模数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感觉这套题强行撸下来真是超神了,头发都不知道掉了多少。。
一道线段树+最短路的混合使用,强行给CF教育了一发


题目:http://codeforces.com/problemset/problem/787/D
题目大意:
简单点来说就是构造一个图,构造的方法有
1、u v
2、u [l,r]
3、[l,r] u
这三种情况,每种情况都会可以构成权值为c的边
然后问随意一个点到所有点的最短路是多少

由于点数为1e5个,总的构图次数为1e5次
有可能构成的边为1e10,首先点数为1e5,构成之后所用dijkstra时间复杂度是O( n2 )远远不够
于是想到了djikstra+heap优化的O( nlogn )的算法,但是复杂度还是不够,乘上点数总时间复杂度为O( n2logn )
所以。。还需要继续优化,怎么优化呢
看到区间,应该能yy到线段树这种鬼畜的数据结构吧。。没错就是线段树
我们通过线段树来减少边的条数。。至于怎么减少呢。。

我们可以构建两种线段树,一种是从上指到下的,一种是从下指到上的,他们互相访问的权值为0,
当遇到u [l,r]这种情况的时候,让他去指向线段树中相应的区间,即可减少边数,我们把线段树的每一个区间都看成一个点,这样就能构成一个最短路。。。
然后同样的[l,r] u 这种情况,用线段树的区间去指向点,同样把线段树的区间看成点。
线段树所组成的线段,基本上可以看成是O(2)级别的,平均算作是O(2)吧。。
那基本上,你每次无论是点连区间还是区间连点,所构成的线大概也就2条上下

所以,建图的时候,点数应该*5倍,但是由于线少了,被log了一下,所以时间复杂度应该改为O( nlog2n )
这个时间复杂度,对于这题就够了。。简直鬼畜。。


敢问世间何时对我们这种弱渣连DIV2都要虐成狗,强行教育了一波。
好像对于pair在G++ 5.0版本不能这么使用,代码只能在G++11.0下编译。
dalao们都说。敲个线段树再敲个dijkstra就过了。。。确实。但是脑洞很大Orz

/*
@resouces: codeforces 787D
@date: 2017-3-27
@author: QuanQqqqq
@algorithm: 线段树 + dijkstra nlogn 
*/
#include <bits/stdc++.h>

#define MAXN 500005
#define ll long long

using namespace std;

const ll LLINF = 0x3f3f3f3f3fLL;
typedef pair<ll,int> pli;

struct Edge{
    int to,weight;
    Edge(int _to = 0,int _weight = 0) : to(_to),weight(_weight){}
};

priority_queue<pli > Q;
vector<vector<Edge> > G(MAXN);
bool vis[MAXN];
int id[MAXN][2];
vector<int> vs;
ll d[MAXN];
int idx;

void addEdge(int from,int to,int weight){
    G[from].push_back(Edge(to,weight));
}

void build(int l,int r,int rt,int wh){  //wh0为从上到下的线段树,wh1为从下到上的线段树 
    id[rt][wh] = ++idx;
    if(l == r){
        if(wh == 0){
            addEdge(id[rt][wh],l,0);
        } else {
            addEdge(l,id[rt][wh],0);
        }
        return;
    }
    int mid = l + r >> 1;
    build(l,mid,rt << 1,wh);
    build(mid + 1,r,rt << 1 | 1,wh);
    if(wh == 0){
        addEdge(id[rt][wh],id[rt << 1][wh],0);
        addEdge(id[rt][wh],id[rt << 1 | 1][wh],0);
    } else {
        addEdge(id[rt << 1][wh],id[rt][wh],0);
        addEdge(id[rt << 1 | 1][wh],id[rt][wh],0);
    }
}

void get(int l,int r,int L,int R,int rt,int wh){
    if(L <= l && r <= R){
        vs.push_back(id[rt][wh]);
        return;
    }
    int m = l + r >> 1;
    if(m >= L){
        get(l,m,L,R,rt << 1,wh);
    }
    if(m < R){
        get(m + 1,r,L,R,rt << 1 | 1,wh);
    }
}

void dijkstra(int s,int n){
    for(int i = 1;i <= n;i++){
        vis[i] = false;
        d[i] = LLINF;
    }
    Q.push({-0,s});
    d[s] = 0;
    while(!Q.empty()){
        int u = Q.top().second;
        Q.pop();
        if(vis[u]){
            continue;
        }
        vis[u] = true;
        for(int i = 0;i < G[u].size();i++){
            Edge e = G[u][i];
            int v = e.to,w = e.weight;
            if(w + d[u] < d[v]){
                d[v] = w + d[u];
                Q.push({-d[v],v});
            }
        }
    }
}

void init(int n){
    while(!Q.empty()){
        Q.pop();
    }
    for(int i = 1;i <= n;i++){
        G[i].clear();
    }
}

int main(){
    int n,q,s,l,r,t,u,v,c;
    scanf("%d %d %d",&n,&q,&s);
    init(n * 5);
    idx = n;
    build(1,n,1,0);
    build(1,n,1,1);
    while(q--){
        scanf("%d %d",&t,&u);
        if(t == 1){
            scanf("%d %d",&v,&c);
            addEdge(u,v,c);
        } else if(t == 2) {
            vs.clear();
            scanf("%d %d %d",&l,&r,&c);
            get(1,n,l,r,1,0);
            for(int i = 0;i < vs.size();i++){
                addEdge(u,vs[i],c);
            }
        } else {
            vs.clear();
            scanf("%d %d %d",&l,&r,&c);
            get(1,n,l,r,1,1);
            for(int i = 0;i < vs.size();i++){
                addEdge(vs[i],u,c);
            }
        }
    }
    dijkstra(s,5 * n);
    for(int i = 1;i <= n;i++){
        if(d[i] == LLINF){
            d[i] = -1;
        }
        printf("%lld ",d[i]);
    }
}

另:这套DIV还有dalao直播讲题解。。Orz弱校渣终于得到了dalao的直播真传,厉害了。。
http://www.bilibili.com/video/av9365298/

### Codeforces 1487D Problem Solution The problem described involves determining the maximum amount of a product that can be created from given quantities of ingredients under an idealized production process. For this specific case on Codeforces with problem number 1487D, while direct details about this exact question are not provided here, similar problems often involve resource allocation or limiting reagent type calculations. For instance, when faced with such constraints-based questions where multiple resources contribute to producing one unit of output but at different ratios, finding the bottleneck becomes crucial. In another context related to crafting items using various materials, it was determined that the formula `min(a[0],a[1],a[2]/2,a[3]/7,a[4]/4)` could represent how these limits interact[^1]. However, applying this directly without knowing specifics like what each array element represents in relation to the actual requirements for creating "philosophical stones" as mentioned would require adjustments based upon the precise conditions outlined within 1487D itself. To solve or discuss solutions effectively regarding Codeforces' challenge numbered 1487D: - Carefully read through all aspects presented by the contest organizers. - Identify which ingredient or component acts as the primary constraint towards achieving full capacity utilization. - Implement logic reflecting those relationships accurately; typically involving loops, conditionals, and possibly dynamic programming depending on complexity level required beyond simple minimum value determination across adjusted inputs. ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; vector<long long> a(n); for(int i=0;i<n;++i){ cin>>a[i]; } // Assuming indices correspond appropriately per problem statement's ratio requirement cout << min({a[0], a[1], a[2]/2LL, a[3]/7LL, a[4]/4LL}) << endl; } ``` --related questions-- 1. How does identifying bottlenecks help optimize algorithms solving constrained optimization problems? 2. What strategies should contestants adopt when translating mathematical formulas into code during competitive coding events? 3. Can you explain why understanding input-output relations is critical before implementing any algorithmic approach? 4. In what ways do prefix-suffix-middle frameworks enhance model training efficiency outside of just tokenization improvements? 5. Why might adjusting sample proportions specifically benefit models designed for tasks requiring both strong linguistic comprehension alongside logical reasoning skills?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值