一道不错的题目。
首先先%%%FK大佬教我做这道题和它的亿点细节
如果只有n,n+1,答案循环节为n+1
如果只有n,n-1,答案循环节为n
现在有n-1,n,n+1
那么n-1,n不会变,n+1在每n位中会往后移动1位
并且呢,一个n-1和n+1相碰会变成n(n+1在前)
那么记last,next为n+1上一个n-1,n-1下一个n+1
当a[x%n]==n-1时,判断时间是否大于x
时间是(x-last[x])*(x+1),如果大于,输出n,否则输出n-1
当a[x%(n+1)]==n+1时同理
如果以上情况都不满足,输出n
细节:
1,记得它是一个环
2,两个条件可能满足,注意特判
3,%(n+1)可能等于n,将a[n]求出来。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
ll i,j,k,m,n,o,p,l,s,t,times;
ll a[1000005],b[1000005],g[1000005],c[1000005],nxt[1000005],las[1000005],z[1000005],bz[1000005];
void read(ll &x)
{
char ch=getchar();x=0;
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-48,ch=getchar();
}
int main()
{
freopen("way.in","r",stdin);
freopen("way.out","w",stdout);
read(times);
while (times--)
{
memset(las,-1,sizeof(las));
memset(nxt,-1,sizeof(nxt));memset(g,0,sizeof(g));
memset(bz,0,sizeof(bz));z[0]=0;
read(n),read(m);
for (i=0;i<=n-1;i++) read(a[i]);
for (i=0;i<=(n-1)*2;i++) b[i]=a[i%n];
for (i=1;i<=(n-1)*2;i++)
{
if (b[i]==n+1&&!bz[i%n]) z[++z[0]]=i,bz[i%n]=1;
if (b[i]==n-1&&nxt[z[z[0]]%n]==-1&&z[0]&&!g[i%n])
{
if (z[z[0]]==70)
{
int adg=0;
}
nxt[z[z[0]]%n]=i%n,z[0]--,g[i%n]=1;
}
}
z[0]=0;memset(bz,0,sizeof(bz));memset(g,0,sizeof(g));
for (i=1;i<=(n-1)*2;i++)
{
if (b[i]==n+1&&!bz[i%n]) z[++z[0]]=i,bz[i%n]=1;
if (b[i]==n-1&&las[i%n]==-1&&z[0]&&!g[z[z[0]]%n])
{
las[i%n]=z[z[0]]%n,g[z[z[0]]%n]=1,z[0]--;
}
}
memset(bz,0,sizeof(bz));z[0]=0;
for (i=0;i<=n-1;i++) a[n]+=(a[i]<=n-i);
for (i=1;i<=m;i++)
{
if (i==19)
{
int gsf=0;
}
read(c[i]);
ll x=c[i];
if (a[x%(n+1)]==n+1&&a[x%n]==n-1)
{
ll y=x%n,Y=x%(n+1);
if (las[y]==-1) printf("%lld ",n-1);
else if (nxt[Y]==-1) printf("%lld ",n+1);
else if ((y-las[y]+n)%n*(n+1)>c[i]) printf("%lld ",n-1);
else if ((nxt[Y]-Y+n)%n*(n+1)>c[i]) printf("%lld ",n+1);
else printf("%lld ",n);
} else if (a[x%n]==n-1)
{
ll y=x%n;
if (las[y]==-1) printf("%lld ",n-1);
else {
if ((y-las[y]+n)%n*(n+1)<=c[i]) printf("%lld ",n);
else printf("%lld ",n-1);
}
}
else if (a[x%(n+1)]==n+1)
{
ll y=x%(n+1);
if (nxt[y]==-1) printf("%lld ",n+1);
else {
if ((nxt[y]-y+n)%n*(n+1)<=c[i]) printf("%lld ",n);
else printf("%lld ",n+1);
}
} else printf("%lld ",n);
}
puts("");
}
return 0;
}