题意有点复杂 大概操作是每次取最前面的两个数,然后大的放队首 小的放队末
每次移动的时候编号随之移动(每个数都有编号 所有的数是一个乱的排列)
问给你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;
}
/*
*/