Aizu - 2782 C - We don‘t wanna work!

https://vjudge.net/contest/145955#problem/C

这题朴素想法就是平衡树模拟操作一下就行了

但因为可以离线,而且前后顺序是影响先后的,所以我们可以把所有加入的人搞个离散化,值为第一关键字,进队时间为第二关键字排个序

然后他们的下标就可以体现他们的相对大小了,每个人都是不同的,而且对于相同名字不同时间进来的人,也是不同的

那么最后就是树状数组上修改查询二分一下的事情了

#include<bits/stdc++.h>
using namespace std;

const int maxl=2e5+10;

int n,m,tot;
struct mem
{
	string nam;int t,val,id;
}a[maxl];
struct que
{
	string op,nam;int val,rk;
}q[maxl];
int b[maxl];
map<string,int> mp;

inline bool cmp(const mem &a,const mem &b)
{
	if(a.val==b.val)
		return a.t>b.t;
	return a.val>b.val;
}

inline void add(int i,int x)
{
	while(i<=tot)
		b[i]+=x,i+=i&-i;
}

inline int sum(int i)
{
	int ret=0;
	while(i)
		ret+=b[i],i-=i&-i;
	return ret;
}

inline int findk(int k)
{
	int ans=0,cnt=0;
	for(int i=20;i>=0;i--)
	if(ans+(1<<i)<=tot && cnt+b[ans+(1<<i)]<k)
		ans+=1<<i,cnt+=b[ans];
	return ans+1;
}

inline void prework()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].nam>>a[i].val;
		a[i].t=i;
	}
	tot=n;cin>>m; 
	for(int i=1;i<=m;i++)
	{
		cin>>q[i].op>>q[i].nam;
		if(q[i].op[0]=='+')
		{
			cin>>q[i].val;
			a[++tot]=mem{q[i].nam,n+i,q[i].val,i};
		}
	}
	sort(a+1,a+1+tot,cmp);
	for(int i=1;i<=tot;i++)
	if(a[i].t<=n)
	{
		add(i,1);
		mp[a[i].nam]=i;
	}
	else
		q[a[i].id].rk=i;
}

inline void mainwork()
{
	int res=n;
	for(int i=1;i<=m;i++)
	if(q[i].op[0]=='+')
	{
		res++;add(q[i].rk,1);mp[q[i].nam]=q[i].rk;
		if(res/5>(res-1)/5)
		{
			if(sum(q[i].rk)<=res/5)
				cout<<q[i].nam<<" is working hard now."<<'\n';
			else
			{
				cout<<q[i].nam<<" is not working now."<<'\n';
				cout<<a[findk(res/5)].nam<<" is working hard now."<<'\n';
			}
		}
		else
		{
			if(sum(q[i].rk)<=res/5)
			{
				cout<<q[i].nam<<" is working hard now."<<'\n';
				cout<<a[findk(res/5+1)].nam<<" is not working now."<<'\n';
			}
			else
				cout<<q[i].nam<<" is not working now."<<'\n';
		}
	}
	else
	{
		res--;int rk=mp[q[i].nam];
		if(res/5<(res+1)/5)
		{
			if(sum(rk)>(res+1)/5)
				cout<<a[findk((res+1)/5)].nam<<" is not working now."<<'\n';
		}
		else
		{
			if(sum(rk)<=(res+1)/5)
				cout<<a[findk((res+1)/5+1)].nam<<" is working hard now."<<'\n';
		}
		add(rk,-1);
	}
}

int main()
{
	prework();
	mainwork();
//	print();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/113405515
we
今日推荐