CF625E Frog Fights 题解
用链表维护青蛙,任意两只青蛙之间没有别的青蛙
用set把青蛙按照"能干掉下一只青蛙的时间"从小到大排序
每次取出最小值更新即可
这里有一个小trick:关于为什么要将\(p_i\)加上\(calc(i,nxt_i)\)呢
对于这个要跳的青蛙(叫做A)之前的青蛙,A跳完之后步数-1,青蛙A跳之前前面青蛙先跳(相当于追A)的时候,以A的步数为\(a_i\)算的,后面A撞飞青蛙完之后以\(a_{i}-1\)来追的,所以要补上
#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
#define int long long
set<pair<int,int> > st; 
const int INF = 1<<30;
const int N = 100005;
int p[N],n,m;
int nxt[N],pre[N];
int a[N],x[N];
inline int read() {
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
bool cmp(int x,int y) {
	return p[x] < p[y];
}
int calc(int x,int y) {
	if(x == y) return INF;
	int d = (p[y]-p[x]+m) % m;
	//默认x先跳,当y先跳时先加上 
	if(x > y) d = (d + a[y]) % m;
	//特判 
	if(d <= a[x]) return 1; 
	//x比y跑的慢,永远追不上 
	if(a[x] <= a[y]) return INF;
	int dis = a[x]-a[y];
	//如果追上了,就不用再跳a[y] 
	return (d-a[y]-1)/dis+1; 
} 
signed main () {
	n = read();m = read();
	for(int i = 1;i <= n;i++) {
		p[i] = read();
		a[i] = read();
		x[i] = i;
	}
	sort(x+1,x+n+1,cmp);
	for(int i = 1;i <= n;i++) {
		if(i < n) nxt[x[i]] = x[i+1];
		else nxt[x[i]] = x[1];
		pre[nxt[x[i]]] = x[i];
	}
	for(int i = 1;i <= n;i++) {
		st.insert(make_pair(calc(i,nxt[i]),i));
	}
	while(!st.empty()) {
		set<pair<int,int> >::iterator it = st.begin();
		if((*it).first == INF) break;
		int i = (*it).second;
		st.erase(it);
		st.erase(make_pair(calc(nxt[i],nxt[nxt[i]]),nxt[i]));
		st.erase(make_pair(calc(pre[i],i),pre[i]));
		p[i] += calc(i,nxt[i]);
		--a[i];
		nxt[i] = nxt[nxt[i]];
		pre[nxt[i]] = i;
		st.insert(make_pair(calc(pre[i],i),pre[i]));
		st.insert(make_pair(calc(i,nxt[i]),i));
	}
	printf("%d\n",st.size());
	for(set<pair<int,int> >::iterator it = st.begin();it != st.end();it++) printf("%lld ",(*it).second);
}
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号