| 比赛 |
2026.3.28 |
评测结果 |
AAAAAAAAAAA |
| 题目名称 |
Good Cyclic Shifts |
最终得分 |
100 |
| 用户昵称 |
RpUtl |
运行时间 |
5.112 s |
| 代码语言 |
C++ |
内存使用 |
15.29 MiB |
| 提交时间 |
2026-03-28 12:30:18 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int n,p[N],c[N];
vector<int>ans;
void add(int x,int y){
for(;x<=n;x+=(x&-x))c[x]+=y;
return;
}
int ask(int x,int cnt=0){
for(;x>0;x-=(x&-x))cnt+=c[x];
return cnt;
}
ll sum[N<<2],val[N<<2],f[N],g[N];
#define ls (p<<1)
#define rs (p<<1|1)
void pushup(int p){
sum[p]=sum[ls]+sum[rs];
val[p]=val[ls]+val[rs];
}
void upd(int p,int l,int r,int x,int v){
if(l==r){
sum[p]+=v*x,val[p]+=v;
}else{
int mid=(l+r)>>1;
if(x<=mid)upd(ls,l,mid,x,v);
if(x>mid)upd(rs,mid+1,r,x,v);
pushup(p);
}
return;
}
ll ask(int p,int l,int r,int L,int R){
if(L<=l&&r<=R)return sum[p];
int mid=(l+r)>>1;ll cnt=0;
if(L<=mid)cnt+=ask(ls,l,mid,L,R);
if(R>mid)cnt+=ask(rs,mid+1,r,L,R);
return cnt;
}
ll count(int p,int l,int r,int L,int R){
if(L<=l&&r<=R)return val[p];
int mid=(l+r)>>1;ll cnt=0;
if(L<=mid)cnt+=count(ls,l,mid,L,R);
if(R>mid)cnt+=count(rs,mid+1,r,L,R);
return cnt;
}
void build(int p,int l,int r){
sum[p]=val[p]=0;
if(l==r)return;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
return;
}
#undef ls
#undef rs
void work(){
scanf("%d",&n);
build(1,-n,n);
for(int i=1;i<=n;i++){
scanf("%d",p+i);
f[i]=g[i]=0;
}
for(int i=1;i<=n;i++){
f[1]+=i-1-ask(p[i]);
add(p[i],1);
}
for(int i=1;i<=n;i++)c[i]=0;
for(int i=1;i<n;i++){
f[i+1]=f[i]+n-2*p[i]+1;
}
for(int i=1;i<=n;i++){
upd(1,-n,n,p[i]-i,1);
g[1]+=abs(p[i]-i);
}
for(int i=1,k;i<n;i++){
upd(1,-n,n,p[i]-i,-1);k=i;
upd(1,-n,n,p[i]-n-k,1);
ll cnt0=count(1,-n,n,-n,-k);
ll sum0=ask(1,-n,n,-n,-k);
ll cnt1=count(1,-n,n,-k+1,n);
ll sum1=ask(1,-n,n,-k+1,n);
g[i+1]=-sum0-cnt0*k+cnt1*k+sum1;
}
ans.clear();
for(int i=1;i<=n;i++){
g[i]/=2;
if(f[i]<=g[i])ans.push_back((n-i+1)%n);
}
sort(ans.begin(),ans.end());
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
if(i)printf(" ");
printf("%d",ans[i]);
}
printf("\n");
return;
}
int main(){
freopen("Shifts.in","r",stdin);
freopen("Shifts.out","w",stdout);
int T;scanf("%d",&T);
while(T--)work();
return 0;
}