Description
Input
Output
Sample Input
Sample 1:
4
3 2 1 4
Sample 2:
2
1 2
Sample Output
Sample 1:
4
Sample 2:
2
Data Constraint
Hint
Solution
对于第i个位置上的数,它必须移动到第a[i]个位置上他才能是固定的数,我们发现可以将每个数旋转到自己位置上的操作的旋转中心求出来,将i挂在旋转中心上,然后将i到旋转中心的距离从小到大排个序,然后往左右扩展旋转中心上的所有点,答案可以O(1)求。因为旋转中心只有2n个,而最多有n个数被挂在旋转中心上,因此时间复杂度为O(n log n)。
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
#define I int
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define N 100010
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
I rd(){
I x=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*w;
}
I o,n,a[N],s[N],p,d[N],l[N*2],nx[N*2],t[N*2],ans;
void add(I x,I y){
t[++t[0]]=y;nx[t[0]]=l[x];l[x]=t[0];
}
I cmp(I x,I y){return abs(x-o)<abs(y-o);}
I cmp2(I x,I y){
I s1=x<=o?o-x:x-o-1,s2=y<=o?o-y:y-o-1;
return s1<s2;
}
I main(){
open("rotate");
n=rd();
F(i,1,n){
a[i]=rd();
if(a[i]>i){
p=a[i]-i+1;
if(p&1) add(i+p/2,i);
else add(n+i-1+p/2,i);
}
else{
p=i-a[i]+1;
if(p&1) add(a[i]+p/2,i);
else add(n+a[i]-1+p/2,i);
}
s[i]=s[i-1]+(a[i]==i);
}
F(i,1,n*2-1){
d[0]=0;
for(I k=l[i];k;k=nx[k]) d[++d[0]]=t[k];
o=i;
if(i<=n) sort(d+1,d+1+d[0],cmp);
else{
o-=n;
sort(d+1,d+1+d[0],cmp2);
}
F(j,1,d[0]){
I x=d[j];
if(x<a[x]) ans=max(ans,s[n]-s[a[x]]+s[x-1]+j);
else ans=max(ans,s[n]-s[x]+s[a[x]-1]+j);
}
}
printf("%d\n",ans);
return 0;
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/98998415