zoukankan      html  css  js  c++  java
  • 【模拟8.07】旋转子段(性质分析)

    60分

    n^2的暴力很显然嘛........

    枚举每个固定点,用个指针向区间两边扫

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<string>
     7 #include<map>
     8 #include<vector>
     9 #define MAXN 100000
    10 using namespace std;
    11 int n;int sum;int a[MAXN];
    12 int biao[MAXN];
    13 int read()
    14 {
    15     int x=0;char c=getchar();
    16     while(c<'0'||c>'9')c=getchar();
    17     while(c>='0'&&c<='9')
    18     {
    19           x=(x<<1)+(x<<3)+(c^48);
    20           c=getchar();
    21     }
    22     return x;
    23 }
    24 int maxn;
    25 int main()
    26 {
    27    n=read();
    28    for(int i=1;i<=n;++i)
    29    {
    30        a[i]=read();
    31        if(a[i]==i)
    32        {
    33             sum++;
    34             biao[i]=1;
    35        }
    36    }
    37    maxn=sum;
    38    for(int i=1;i<=n;++i)
    39    {
    40        int point_l=i-1;int point_r=i+1;int sum_me=sum;
    41        while(a[point_l]!=0&&a[point_r]!=0)
    42        {
    43             if(biao[point_l])sum_me--;
    44             if(biao[point_r])sum_me--;
    45             swap(a[point_l],a[point_r]);
    46             if(a[point_l]==point_l)sum_me++;
    47             if(a[point_r]==point_r)sum_me++;
    48             maxn=max(sum_me,maxn);
    49             swap(a[point_l],a[point_r]);
    50             //printf("point_l=%d point_r=%d sum_me=%d
    ",point_l,point_r,sum_me);
    51             point_l--;point_r++;
    52        }
    53        point_l=i;point_r=i+1;sum_me=sum;
    54        while(a[point_l]!=0&&a[point_r]!=0)
    55        {
    56             if(biao[point_l])sum_me--;
    57             if(biao[point_r])sum_me--;
    58             swap(a[point_l],a[point_r]);
    59             if(a[point_l]==point_l)sum_me++;
    60             if(a[point_r]==point_r)sum_me++;
    61             maxn=max(sum_me,maxn);
    62             swap(a[point_l],a[point_r]);
    63             //printf("---point_l=%d point_r=%d sum_me=%d
    ",point_l,point_r,sum_me);
    64             point_l--;point_r++;
    65        }
    66    }
    67    printf("%d
    ",maxn);
    68 }
    View Code

    100分n*log(n)

    假设有个点位置为i权值为a[i]

    那么显然它想要作出贡献只能是以(i+a[i])/2为旋转点

    那么我们发现,假设我们排序一边(以固定点为关键字),

    然后就我们发现(对于同一旋转点)假设从一个区间较小->区间较大,

    贡献值的变化只有旋转后,变回相应位置的点,贡献++

    同时会有一部分点原来是i==a[i],这些点的贡献减去,前缀和处理

      1 //性质::区间的外围一定是可作出贡献点
      2 //排序后每次可贡献点++,固定点--
      3 #include<cstdio>
      4 #include<iostream>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<cstring>
      8 #include<string>
      9 #include<map>
     10 #include<vector>
     11 #define MAXN 500000
     12 #define ps push_back
     13 #define int long long
     14 using namespace std;
     15 struct node{int l,r,dian,len;}e1[MAXN],e2[MAXN];
     16 int a[MAXN];
     17 int sum[MAXN],biao[MAXN];
     18 int n,maxn;
     19 bool cmp(const node &a,const node &b)
     20 {
     21      return (a.dian==b.dian)?(a.len<b.len):(a.dian<b.dian);
     22 }
     23 signed main()
     24 {
     25     scanf("%lld",&n);
     26     for(int i=1;i<=n;++i)
     27     { 
     28         scanf("%lld",&a[i]);
     29         sum[i]=sum[i-1];
     30         if(a[i]==i)
     31         {
     32            biao[i]++;
     33            sum[i]++;
     34         }   
     35     }
     36     int tot1=0,tot2=0;
     37     for(int i=1;i<=n;++i)
     38     {
     39         if((i+a[i])%2==0)
     40         {
     41            int zh=(i+a[i])/2;
     42            e1[++tot1].l=min(i,a[i]);
     43            e1[tot1].r=max(i,a[i]);
     44            e1[tot1].dian=zh;
     45            e1[tot1].len=abs(a[i]-i)+1;
     46           //printf("e[%lld].dian=%lld %lld %lld
    ",tot1,e1[tot1].dian,e1[tot1].l,e1[tot1].r);   
     47         }
     48         else 
     49         {
     50            int zh=(i+a[i])/2;
     51            e2[++tot2].l=min(i,a[i]);
     52            e2[tot2].r=max(i,a[i]);
     53            e2[tot2].dian=zh;
     54            e2[tot2].len=abs(a[i]-i)+1;
     55         }
     56     }
     57     sort(e1+1,e1+tot1+1,cmp);
     58     sort(e2+1,e2+tot2+1,cmp);
     59    /* for(int i=1;i<=tot1;i++)
     60     {
     61         
     62     }*/
     63     int sum1=0;
     64     for(int i=1;i<=tot1;++i)
     65     {
     66         //printf("i===%lld
    ",i);    
     67         //printf("e[%lld].dian=%lld %lld %lld %lld
    ",i,e1[i].dian,e1[i].l,e1[i].r,e1[i].len);
     68         int l,r;
     69         if(e1[i].dian==e1[i-1].dian)
     70         {
     71             //printf("case 1:
    ");
     72             if(e1[i].len==e1[i-1].len)continue;
     73             l=e1[i].l;r=e1[i].r;
     74             int last_l=e1[i-1].l;int last_r=e1[i-1].r;
     75             if(a[l]==r)sum1++;if(a[r]==l)sum1++;
     76             sum1-=sum[last_l-1]-sum[l];
     77             sum1-=sum[r-1]-sum[last_r];
     78             maxn=max(maxn,sum1);
     79             //printf("sum1=%lld 
    ",sum1);
     80         }
     81         else
     82         {
     83              l=e1[i].l;r=e1[i].r;     
     84              sum1=0;
     85              sum1+=sum[e1[i].l-1];
     86              sum1+=sum[n]-sum[e1[i].r];
     87              if(biao[e1[i].dian]==1)sum1++; 
     88              maxn=max(maxn,sum1);
     89              if(l==r){continue;}
     90              if(a[l]==r)sum1++;
     91              if(a[r]==l)sum1++;
     92              //printf("l=%lld r=%lld sum1=%lld
    ",l,r,sum1);
     93              maxn=max(maxn,sum1);
     94         }
     95 
     96     }
     97     for(int i=1;i<=tot2;++i)
     98     {
     99         int l=0,r=0;
    100         //printf("i=%lld
    ",i);
    101        // //printf("e[%lld].dian=%lld %lld %lld %lld
    ",i,e2[i].dian,e2[i].l,e2[i].r,e2[i].len);
    102         if(e2[i].dian==e2[i-1].dian)
    103         {
    104             if(e2[i].len==e2[i-1].len)continue;
    105             l=e2[i].l;r=e2[i].r;
    106             int last_l=e2[i-1].l,last_r=e2[i-1].r;
    107             if(a[l]==r)sum1++;if(a[r]==l)sum1++;
    108            // printf("sum1=%lld
    ",sum,a[l],r);
    109             sum1-=sum[last_l-1]-sum[l];
    110             sum1-=sum[r-1]-sum[last_r];
    111             maxn=max(maxn,sum1);
    112             //printf("case 1sum=%lld 
    ",sum1);
    113         }
    114         else 
    115         {
    116             l=e2[i].l;r=e2[i].r;sum1=0;
    117             if(a[l]==r)sum1++;
    118             if(a[r]==l)sum1++;
    119             sum1+=sum[l-1];
    120             sum1+=sum[n]-sum[r];
    121             maxn=max(maxn,sum1);
    122            // printf("l=%lld r=%lld sum1=%lld
    ",l,r,sum1);
    123         }
    124     }
    125     printf("%lld
    ",maxn);
    126 }
    127 /*
    128 8
    129 2 3 4 1 5 7 8 6 
    130 */
    View Code
  • 相关阅读:
    4-8(十五)性能测试流程
    数据库面试题(一)多表查询
    4-8(十四) jmeter 性能分析从哪几个方面
    4-8(十二)Jmeter+Ant+Jenkins定时构建
    4-8(十一)Jmeter自动化集成工具Ant的安装
    4-8(十)Jmeter 分布式测试
    4-8(九)Jmeter性能测试之阶梯式场景(负载测试)、波浪式场景(压力测试)
    4-8(八)Jmeter性能测试插件jpgc的安装
    4-8(六)Jmeter 脚本录制后调优
    6分钟演示,15种排序算法(视频)
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11329075.html
Copyright © 2011-2022 走看看