题意: 给定 n 个数, 接下来 m 次操作,每次输入一个 x ,如果数列中存在小于等于x的值,则加上x
错误 : 用优先队列操作,优先队列操作对象是第一个字符,当然也可以自己定义。
题解: 把小于等于x 的数字取出来,放入vector中,然后依次进行加法,之前的想法是用一个while,但是会加多次而不是一次。
分析: 因为x值是有限定的,每个数 a[I] += x ,最多加log(x) 次, 然后这个数就比x的范围大了,永远不会再出队列。
时间复杂度: m * log(n) * log(x)
默认是大跟堆, 注意小跟堆的构造方式
#include<bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define rep(i,l,r) for(int i = l; i <= r; i++)
typedef long long ll;
typedef pair<ll,ll> PII;
const int N = 1e5 + 10;
ll n, m, a[N];
vector<PII> v;
void solve()
{
priority_queue <PII,vector<PII>,greater<PII> > q;
cin >> n >> m;
rep(i,1,n)
{
ll tmp; cin >> tmp;
q.push({tmp,i});
}
rep(i,1,m)
{
ll x; cin >> x;
if(x==0) continue;
while(q.size() and q.top().ff <= x)
v.push_back(q.top()), q.pop();
int len = v.size();
rep(i,0,len-1)
{
auto f = v[i];
f.ff += x;
q.push(f);
}
v.clear();
}
while(q.size())
{
auto t = q.top();
q.pop();
a[t.ss] = t.ff;
}
rep(i,1,n) cout << a[i] << " ";
}
int main()
{
solve();
return 0;
}