考前继续颓废,由于想跑路,所以这套题的题解无比草率,慎读,别说我,我是个标准颓狗了

考场打了个$O(n^2)$的暴力,成功水到70分,由于数据范围是假的,所以被干掉了15分,正解很优秀,要用到其他人正常$O(n^2)$旋转中心的思路,我这么说当时是因为我的$O(n^2)$很清奇咯,我们很容易知道对于一个旋转区间,如果他的两个端点被翻转之后都不能变为固定点,那我们完全可以缩小区间范围,毕竟翻转区间越长,你破坏原本固定点的概率越大,所以我们从头到尾先扫一遍,记录可以使这个点翻转之后成为固定点的区间,把旋转中心是同一个的扔进同一个$vector$中,由于旋转中心是$\frac{l+r}{2}$,不是整数不可做的样子,所以我们就不除2了,一样的用,其实事实上每个$vector$的$size$代表了区间个数,我们可以翻一个,翻两个,翻$size$个,所以说,我们按区间长度由小到大让元素有序,枚举$size$时候的贡献就是$sum[n]-(sum[r]-sum[l-1])+j+1$,$sum[i]$代表前$i$个点中固定点的个数,对所有的贡献取$\max$既可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<algorithm>
 5 #define maxn 500100
 6 using namespace std;
 7 struct node{
 8     int num,pos;
 9 }a[maxn];
10 bool operator < (const node &a,const node &b)
11 {
12     return (a.pos-a.num)<(b.pos-b.num);
13 }
14 int n,ans;
15 int sum[maxn];
16 vector <node> b[maxn*2];
17 int main()
18 {
19     scanf("%d",&n);
20     for(int i=1;i<=n;++i)
21     {
22         scanf("%d",&a[i].num);  a[i].pos=i;
23         if(a[i].num>a[i].pos)  swap(a[i].num,a[i].pos);
24         if(a[i].num==a[i].pos)  sum[i]++;
25         sum[i]+=sum[i-1];  b[a[i].num+a[i].pos].push_back(a[i]);
26     }
27     for(int i=1;i<=2*n;++i)  sort(b[i].begin(),b[i].end());
28     for(int i=1;i<=2*n;++i)
29         for(int j=0;j<b[i].size();++j)
30         {
31             int da=sum[n]-(sum[b[i][j].pos]-sum[b[i][j].num-1])+j+1;
32             ans=max(da,ans);
33         }
34     printf("%d\n",ans);
35     return 0;
36 }
View Code

相关文章:

  • 2022-02-13
  • 2021-08-14
  • 2022-01-12
  • 2021-08-09
  • 2022-12-23
  • 2021-11-23
  • 2021-10-18
猜你喜欢
  • 2021-12-20
  • 2021-12-09
  • 2021-04-29
  • 2021-08-04
  • 2021-11-17
  • 2021-10-04
相关资源
相似解决方案