一道明显的贪心题目,优先处理推迟耗费大的航班,使它尽量耗费较少,这样可使总的耗费较少!但是普通遍历明显会TLE,所以我们可以用并查集跳过已经被占用的时间,记录每一个点的下一个点是谁即可。
具体细节代码里说:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int maxn = 3e5+5;
const int ff = 0x3f3f3f3f;
struct node
{
ll c;
int pos;
}node[maxn];
int n,k;
int ans[maxn];
int ne[maxn*2];//这个数组要开大
bool cmp(struct node a,struct node b)
{
return a.c> b.c;
}
void init()
{
for(int i = 0;i<= maxn*2;i++)
ne[i] = i;
return ;
}
int find(int x)
{
int r = x;
while(x!= ne[x])
x = ne[x];
while(r!= ne[r])//一定要路径压缩,否则很容易超时
{
int t = ne[r];
ne[r] = x;
r = t;
}
return x;
}
int main()
{
cin>>n>>k;
init();
for(int i = 1;i<= n;i++)
{
scanf("%I64d",&node[i].c);
node[i].pos = i;
}
ll sum = 0;
sort(node+1,node+n+1,cmp);
for(int i = 1;i<= n;i++)
{
int fa = find(max(node[i].pos,k+1));
ans[node[i].pos] = fa;
sum+= (fa-node[i].pos)*node[i].c;//运算过程中可能会超int,这里注意
ne[fa] = find(fa+1);
}
cout<<sum<<endl;
for(int i = 1;i<= n;i++)
if(i == n)
printf("%d\n",ans[i]);
else
printf("%d ",ans[i]);
return 0;
}