[二分+(优先队列|前缀和)]Producing Snow CodeForces - 948C

题干 给定长度n(n<=1e5),第一行v[i]表示表示第i堆雪的体积,第二行t[i]表示第1~i天的雪将要消融的体积,一堆雪如果消融到体积为0则消失,求每天消融的雪的体积。
首先是优先队列的…..

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;

const int INF=0x3f3f3f3f;
const int maxn=1e5+5;
int n,m,c1,c2,v,q;
ll T[maxn],V[maxn],ST[maxn];

int main(){
    ST[0]=0;
    while(cin>>n){
        for(int i=1;i<=n;i++) cin>>V[i];
        for(int i=1;i<=n;i++) cin>>T[i];
        for(int i=1;i<=n;i++) ST[i]=ST[i-1]+T[i];

        priority_queue<ll,vector<ll>,greater<ll> > Q;

        for(int i=1;i<=n;i++){
            Q.push(V[i]+ST[i-1]);// 每次都加上 T的前缀和 让ST[i-1]消除 i前天的多的温度 
            ll res=T[i]*Q.size();// 这个时候还存在的雪堆默认都够消融 乘温度  接着进入while中去找不够的 
            while(!Q.empty()&&Q.top()<=ST[i]){//找雪不够融的天 pop掉 并且 那天多加的 减去 
                res+=(Q.top()-ST[i]);//  这里top是本来的-ST[i] 变成我们多加上的 减去即可             
                Q.pop();
            }
            if(i!=1) cout<<" ";
            cout<<res;
        }cout<<endl; 
    }
    return 0;
}

接下来是 练习手写二分 其实可以lower_bound

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <list>
#include <bitset>
using namespace std;
typedef long long ll;

const int maxn=1e5+10;

ll V[maxn],T[maxn],ST[maxn];
ll Q[maxn],RE[maxn];
int n;

int main(){
    ST[0]=0;
    V[0]=0;
    T[0]=0;
    while(cin>>n){
        memset(Q,0,sizeof(Q));
        memset(RE,0,sizeof(RE));
        for(int i=1;i<=n;i++) cin>>V[i];
        for(int i=1;i<=n;i++) cin>>T[i];
        for(int i=1;i<=n+10;i++) ST[i]=ST[i-1]+T[i];

        for(int i=1;i<=n;i++){
        //  Q[i]++;
            ll L=i-1,R=n+10;
            while(R-L>1){//白书还是耐用。。。。。
                ll m=(R+L)>>1;
            //  cout<<L<<"  "<<R<<" "<<m<<endl;
                if(V[i]<=(ST[m]-ST[i-1])) R=m;
                else L=m;
            }
        //  cout<<"  DAS "<<R<<endl;
            Q[i]++,Q[R]--;//第一次使用神奇操作 来记录那天可以有多少堆
            RE[R]+=(V[i]-(ST[R-1]-ST[i-1])); 
        }
    //  for(int i=0;i<=n;i++) 
        for(int i=1;i<=n;i++){
            Q[i]=Q[i-1]+Q[i];
            if(i!=1) cout<<" ";
            cout<<Q[i]*T[i]+RE[i];
        }cout<<endl;
    }
    return 0;
}
### 消息队列与阻塞队列的区别及优势 #### 基本概念 消息队列是一种异步通信机制,用于在不同进程或线程之间传递消息。它通常由操作系统或其他中间件提供支持,能够跨不同的应用程序边界传输数据[^1]。 阻塞队列则是在多线程环境下使用的同步工具类,主要用于协调生产者和消费者之间的协作关系。当队列达到容量上限时,生产者的插入操作会被挂起;而当队列为零时,消费者的移除操作同样会被挂起,直至条件满足[^2]。 --- #### 主要区别 | 特性 | 消息队列 | 阻塞队列 | |-------------------|------------------------------------------|-----------------------------------------| | **适用场景** | 跨进程、分布式环境中的异步消息传递 | 同一进程中多个线程间的任务调度 | | **实现复杂度** | 较高,依赖于外部框架或库 | 较低,内置 Java API 即可完成 | | **持久化能力** | 支持持久化存储 | 不具备持久化功能 | | **扩展性** | 易于水平扩展 | 扩展受限 | | **性能开销** | 可能较高 | 性能更优 | --- #### 优势对比 ##### 消息队列的优势 1. **解耦**: 生产者和消费者无需直接交互即可完成数据交换[^3]。 2. **可靠性**: 多数现代消息队列(如 Kafka, RabbitMQ)提供了可靠的消息投递保障以及失败重试机制。 3. **灵活性 & 可伸缩性**: 客户端可以根据需求动态调整数量而不影响整体架构稳定性。 4. **顺序保证**: 对某些特定类型的消息队列而言,在单分区情况下可以确保消息按发送顺序接收。 5. **延迟容忍度更高**: 如果下游服务暂时不可用,则可以通过积压未处理的数据包来缓解压力。 ##### 阻塞队列的优点 1. **简单高效**: 使用标准库函数构建即可满足大部分内部业务逻辑的需求。 2. **实时性强**: 数据一旦进入缓冲区即刻可供读取方访问,减少了额外网络跳转带来的延时成本。 3. **资源消耗少**: 相较于引入第三方组件来说内存占用更低且配置过程更为简便快捷. --- 以下是两种典型应用场景下代码示例: ```java // 阻塞队列实例 (Java 中的 ArrayBlockingQueue) import java.util.concurrent.ArrayBlockingQueue; public class BlockingQueueExample { public static void main(String[] args) throws InterruptedException { ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10); // Producer Thread Thread producerThread = new Thread(() -> { try { for(int i=0;i<10;i++) { System.out.println("Producing item "+i); queue.put(i); // Blocks when full. } } catch(InterruptedException e){ Thread.currentThread().interrupt(); } }); // Consumer Thread Thread consumerThread = new Thread(() -> { while(true){ try{ Integer value = queue.take(); // Waits until an element is available. System.out.println("Consumed item "+value); }catch(Exception ex){} } }); producerThread.start(); consumerThread.start(); producerThread.join(); consumerThread.interrupt(); } } ``` 对于消息队列的实际应用演示由于涉及较多外部依赖项在此不做赘述,请参阅官方文档获取更多信息。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值