列表

详情


NC206551. 管理时间

描述

最近在学习如何管理时间,其中有一个非常重要的课程叫做制定时间表,例如: 一天中一共要做 件事情,那么他就要将这 件事的先后顺序排列出来。众所周知 是一个心思缜密的人,出于特殊考虑以防日程表泄露,他是这样安排日程表的:首先,他将这 件事情标号并按顺序排列,然后,一共有次操作,每次操作挑选出序号为w_i的事件并把这件事放到最后做。就这样 一天的日程表就完成了。我们并不关心 最后的日程表长什么样,我们关心的是 对每件事的喜爱程度,而 对每一件事的喜爱程度等价于这件事在日程表变化整个过程中所处过最前面的位置。

输入描述

第一行共两个整数 表示一共有 件事情, 次操作。(

第二行共 个整数用空格隔开,第 个整数 表示在第 次操作中我们挑选放到最后的事情的标号。

输出描述

一行共 个整数用空格隔开,第 个整数 表示 对标号为 的事情的喜爱程度。

示例1

输入:

5 4
3 1 2 4

输出:

1 1 2 1 1

说明:

初始的排序为:{1, 2, 3, 4, 5}
第一次操作后:{1, 2, 4, 5, 3}
第二次操作后:{2, 4, 5, 3, 1}
第三次操作后:{4, 5, 3, 1, 2}
第四次操作后:{5, 3, 1, 2, 4}
每个事件对应出现位置的最小值为1, 1, 2, 1, 1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 88ms, 内存消耗: 4796K, 提交时间: 2020-06-23 14:41:04

#include <iostream>
using namespace std;
const int MAXN=400010;
int t[MAXN],n,m;
int lowbit(int x)
{
    return x&(-x);
}

void add(int pos,int val=1)
{
    while(pos<=MAXN)
    {
        t[pos]+=val;
        pos+=lowbit(pos);
    }
}

int ask(int pos)
{
    int ans=0;
    while(pos>=1)
    {
        ans+=t[pos];
        pos-=lowbit(pos);
    }
    return ans;
}

int R[MAXN],no[MAXN];
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        add(i);
        R[i]=no[i]=i;
    }
    for(int i=1;i<=m;i++)
    {
        int x;
        cin>>x;
        R[x]=min(R[x],ask(no[x]));
        add(no[x],-1);
        no[x]=n+i;
        add(no[x]);
    }
    for(int i=1;i<=n;i++)
    {
        R[i]=min(R[i],ask(no[i]));
        cout<<R[i]<<" ";
    }
    
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 122ms, 内存消耗: 7008K, 提交时间: 2020-05-24 16:43:01

#include<iostream>
using namespace std;
int cnt=0;
int a[200005],rem[200005],l[400005],tree[800005],ans[200005];
int N;
int lowbit(int x){
	return x&(-x);
}
void add(int x,int num){
	while(num<=N){
		tree[num]+=x;
		num+=lowbit(num);
	}
}
int ask(int num){
	int ans=0; 
	while(num){
		ans+=tree[num];
		num-=lowbit(num);
	}
	return ans;
}
int main(){
	int n,m;
	cin>>n>>m;
	N=n+m;
	for(int i=1;i<=n;i++){
		a[i]=i;
		rem[i]=i;
		l[i]=i;
		ans[i]=i;
	}
	for(int i=1;i<=m;i++){
		cin>>l[n+i];
		int x=l[n+i];
		add(1,rem[x]+1);
		add(-1,n+i);
		ans[x]=min(ans[x],a[x]-ask(rem[x]));
		a[x]=n;
		add(-9999999,rem[x]);
		add(9999999,rem[x]+1);
		rem[x]=n+i;
	}
	for(int i=1;i<=n;i++){
		ans[i]=min(ans[i],a[i]-ask(rem[i]));
	}
	for(int i=1;i<=n;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}

上一题