C. Fighting Tournament #814 div2

Problem - C - Codeforces

题意有点复杂 大概操作是每次取最前面的两个数,然后大的放队首 小的放队末

每次移动的时候编号随之移动(每个数都有编号 所有的数是一个乱的排列)

问给你q组询问,编号为i的数赢了多少次

刚想骂这题大大模拟,但其实是我自己的问题..
没有捋清楚就直接敲代码,越写越乱,最后...

但其实这题挺好的QAQ 要把思路想清楚再写 主要赛时有点着急了 前面做慢了,但前面做的慢了 后面才要稳一点呀,害,下次注意!

思路:每次移动,只要最大的数被移动到第一个的时候,那序列的第一个就不再变了

这样移动的最坏复杂度是O(n)的,所以前面的遍历一下,超过n次全部都是最大的数

把每次的赢的轮数记录一下,比如7这个数赢了2 3 4轮。k如果是3,意思就是前三轮7赢的次数(不过查询的是编号),二分查找一下大于第三轮的下标(upper_bound)下标是0,1,2。所以是两轮,如果查找的数是最大的数,还要加上n轮之后所有的次数

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#define IOS ios::sync_with_stdio(false), cin.tie(0);
#include<iostream>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
using namespace std;
typedef long long ll;
typedef pair<int,int> PAII;
const int N=2e6+10,M=5050,INF=0x3f3f3f3f,mod=998244353;
deque<int> q;
vector<int> v[N];
int a[N];
int main(){
	IOS; 
	int T;
	//T=1;
	cin>>T;
	while(T--)
	{
		q.clear();
		int n,Q;
		cin>>n>>Q;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			v[i].clear();
			q.push_back(i);
		}
		for(int i=1;i<=n;i++)//最多只会遍历n遍
		{
			int x=q.front();q.pop_front();
			int y=q.front();q.pop_front();
			if(a[x]<a[y]) swap(x,y);
			q.push_front(x);
			q.push_back(y);
			v[x].push_back(i);
		}
		while(Q--)
		{
			int id,k;
			cin>>id>>k;
			int res=upper_bound(v[id].begin(),v[id].end(),k)-v[id].begin();
			if(a[id]==n) res+=max(0,k-n);
			cout<<res<<"\n"; 
		}
	}
	return 0;
}
/*


 
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值