比赛 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;
}