有\(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;
}

CF625E Frog Fights的更多相关文章

  1. 【CF625E】Frog Fights(模拟)

    [CF625E]Frog Fights(模拟) 题面 CF 洛谷 翻译: 有\(n\)只青蛙在一个被分为了\(m\)等分的圆上,对于每份顺时针依次标号. 初始时每只青蛙所在的位置是\(p_i\),速度 ...

  2. Codeforces Round #342 (Div. 2) E. Frog Fights set 模拟

    E. Frog Fights 题目连接: http://www.codeforces.com/contest/625/problem/E Description stap Bender recentl ...

  3. Codeforces Round #342 (Div 2) 解题报告

    除夕夜之有生之年CF第一场 下午从奶奶家回到姥姥家,一看还有些时间,先吃点水果陪姥姥姥爷聊了会儿,再一看表,5:20....woc已经开场20分钟了...于是抓紧时间乱搞.. **A. Guest F ...

  4. [LeetCode] Frog Jump 青蛙过河

    A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...

  5. hdu5037 Frog (贪心)

    http://acm.hdu.edu.cn/showproblem.php?pid=5037 网络赛 北京 比较难的题 Frog Time Limit: 3000/1500 MS (Java/Othe ...

  6. CF #305 (Div. 2) C. Mike and Frog(扩展欧几里得&&当然暴力is also no problem)

    C. Mike and Frog time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  7. Frog Jump

    A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...

  8. POJ 1054 The Troublesome Frog

    The Troublesome Frog Time Limit: 5000MS Memory Limit: 100000K Total Submissions: 9581 Accepted: 2883 ...

  9. Leetcode: Frog Jump

    A frog is crossing a river. The river is divided into x units and at each unit there may or may not ...

随机推荐

  1. element ui 左侧导航栏

    <el-menu class="left-menu" :default-active="$route.name" :unique-opened=" ...

  2. exp(cos(t)) - 2*cos(4.*t) + (sin(t./12)).^5;图形

    clc; clear all; close all; t = linspace(0,24*pi,1000); r = exp(cos(t)) - 2*cos(4.*t) + (sin(t./12)). ...

  3. Java基础进阶:APi使用,Math,Arrarys,Objects工具类,自动拆装箱,字符串与基本数据类型互转,递归算法源码,冒泡排序源码实现,快排实现源码,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    要点摘要 Math: 类中么有构造方法,内部方法是静态的,可以直接类名.方式调用 常用: Math.abs(int a):返回参数绝对值 Math.ceil(double a):返回大于或等于参数的最 ...

  4. Python处理邮件内容和提取邮件里的url地址

    最近在搞一个邮箱验证账号注册和登录的模块.总结一下.就当记载.文章中涉及到域名和邮箱等都经过处理. 需求是这样子的,注册某个网站的账号,然后注册需要邮件内容激活,登录的时候如果不是常用设备的话也需要认 ...

  5. matplotlib之scatter

    Matplotlib之scatter 1,使用scatter绘制散点图并设置其样式: 1 import matplotlib.pyplot as plt 2 3 '''使用scatter绘制散点图并设 ...

  6. (九)rmdir和rm -r删除目录命令

    一.命令描述与格式 rmdir用于删除空目录 命令格式 :rmdir   [选项]   目录名 选项: --ignore-fail-on-non-empty   :忽略任何因目录仍有数据而造成的错误 ...

  7. 简单了解一下 Nginx

    一.Nginx 基本认识 1.Nginx 是什么? Nginx 是一款开源的.轻量级的.高性能的 HTTP 服务器 以及 反向代理服务器. 特点是 占有内存少.并发能力强. 2.Nginx 用来干什么 ...

  8. CVE-2017-10271漏洞复现

    漏洞描述 Weblogic的WLS Security组件对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML数据,在解析的过程中出现反序列化漏洞,导致可执行任意命令. ...

  9. 痞子衡嵌入式:MCUXpresso IDE下SDK工程导入与workspace管理机制

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下SDK工程导入与workspace管理机制. MCUXpresso IDE是恩智浦软件团队倾注很大心血研发 ...

  10. jfinal项目报java.lang.ClassNotFoundException: com.jfinal.core.JFinalFilter

    在eclipse中启动jfinal项目时,项目报错如下:首先:右击项目–>Build Path–>Source查看Default output folder如果是目录/WEB-INF/cl ...