ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF625E Frog Fights

2021-01-22 18:35:46  阅读:192  来源: 互联网

标签:nxt int Fights 青蛙 Frog st rg CF625E define


有\(n\)只青蛙在一个长度为\(m\)的环上打架;每只青蛙有一个初始位置\(p_i\),和一个跳跃数值\(a_i\)。从\(1\)号青蛙开始按序号循环行动,每次若第\(i\)只青蛙行动,则它会向前跳 \(a_i\)个格子,撞飞它遇见的所有青蛙,包括终点格子上的,之后它的\(a_i\)减少等同于撞飞的青蛙只数,若\(a_i<0\),它不会移动。求最后剩下的所有青蛙的编号。\(n\leq 10^5,m\leq 10^9\),\(p\)互不不同


这类问题就往相对位置的方向想吧,,,

在第一次有青蛙撞飞其他青蛙之前,他们的相对位置都是不变的。所以考虑优化最朴素的模拟,即维护出第一次撞飞别人是什么时候以及哪只青蛙撞。所以一个优化的算法就是撞飞一只青蛙之后重新计算所有青蛙的位置。又由于每个青蛙只需要注意它正前方的那只,所以我们可以做一个链表来维护青蛙的相对位置。这样复杂度还是很高。但可以发现撞飞别人以后仍然有很多青蛙的相对位置没有变。如果我们每次都通过\(初始距离之差/a之差\)来计算青蛙相撞的时间,当某只青蛙撞完别人并且a减1之后,我们仍然用这个公式算就会有误差。假设这只青蛙在\(t\)时刻撞了别人,可以发现我们让它的位置往前挪\(t\)个单位就可以消除这个误差。所以我们就有一个新的算法,即每次相撞后修改一下撞击者的位置。这样就是\(O(nlogn)\)了。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define cn const
#define gc getchar()
#define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)
#define fb(i,a,b) for(rg int i=(a),ed=(b);i>=ed;--i)
#define mp make_pair
using namespace std;
typedef cn int cint;
typedef pair<int,int> pr;
il int rd(){
	rg int x(0),f(1); rg char c(gc);
	while(c<'0'||'9'<c){if(c=='-')f=-1;c=gc;}
	while('0'<=c&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=gc;
	return x*f;
}
cint maxn=1e5+10,inf=0x3f3f3f3f;
int n,m,pre[maxn],nxt[maxn];
set<pr> st;
struct frog{int p,a,id;}a[maxn];
il bool cmp(cn frog &a,cn frog &b){return a.p<b.p;}
il bool cmp2(cn frog &a,cn frog &b){return a.id<b.id;}
il int calc(int x,int y){
	frog p=a[x],q=a[y];
	rg int res=0;
	if(x<y){
		rg int tmp=p.p,now=tmp+p.a,now2=q.p;
		p.p=(p.p+p.a-1)%m+1,res=1;
		if(now2<tmp)now2+=m;
		if(tmp<=now2&&now2<=now)return 1;
	}
	rg int dis=(q.p-p.p+m)%m,dec=p.a-q.a;
	if(dec<=0)return inf;
	return res+(dis+dec-1)/dec;
}
int main(){
	n=rd(),m=rd();
	fp(i,1,n)a[i].p=rd(),a[i].a=rd(),a[i].id=i;
	sort(a+1,a+1+n,cmp);
	pre[a[1].id]=a[n].id,nxt[a[1].id]=a[2].id,nxt[a[n].id]=a[1].id,pre[a[n].id]=a[n-1].id;
	fp(i,2,n-1)pre[a[i].id]=a[i-1].id,nxt[a[i].id]=a[i+1].id;
	sort(a+1,a+1+n,cmp2);
	fp(i,1,n)st.insert(mp(calc(i,nxt[i]),i));
	int fl=0;
	while(st.size()){
		set<pr>::iterator it=st.begin();
		if(it->first==inf)break;
		rg int i=it->second,tem=it->first;
		st.erase(it);
		st.erase(mp(calc(nxt[i],nxt[nxt[i]]),nxt[i]));
		st.erase(mp(calc(pre[i],i),pre[i]));
		--a[i].a,a[i].p=(a[i].p+tem-1)%m+1;
		pre[nxt[nxt[i]]]=i,nxt[i]=nxt[nxt[i]];
		st.insert(mp(calc(pre[i],i),pre[i]));
		st.insert(mp(calc(i,nxt[i]),i));
	}
	printf("%d\n",st.size());
	for(auto &x:st)printf("%d ",x.second);
	return 0;
}

标签:nxt,int,Fights,青蛙,Frog,st,rg,CF625E,define
来源: https://www.cnblogs.com/akura/p/14314749.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有