zoukankan      html  css  js  c++  java
  • [51nod1410]回文调整

      给一个序列,选择其中一个区间,这个区间内的数字顺序可以随意互换。问有多少这样的选择使得整个序列(不是选择的区间)是一个回文。
      说明:为了要使得整个序列是一个回文,可以选择一个区间对里面的数字进行调整,然后使得整个串是一个回文。
      问有多少这样的区间可供选择?

     Input
      输入共2行。
      第一行有一个整数n。(1 <= n <= 100,000)
      第二行n个整数a[i],(0<=a[i]<=n).
     Output
      对于每一组数据,输出答案占一行。

      还是跑去cf上看题解...

      先把两端回文的去掉,对于剩下的,分别求出要使序列合法,需要选择的最短前缀、后缀。然后就可以算了。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #define ll long long
     7 #define ui unsigned int
     8 #define ull unsigned long long
     9 const int maxn=100233,inf=1002333333;
    10 int a[maxn],b[maxn],rest[maxn],need[maxn];
    11 int i,j,k,n,m;
    12 
    13 int ra,fh;char rx;
    14 inline int read(){
    15     rx=getchar(),ra=0,fh=1;
    16     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
    17     if(rx=='-')fh=-1,rx=getchar();
    18     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
    19 }
    20 
    21 
    22 int main(){register int i,j;
    23     while(scanf("%d",&n)!=EOF){
    24         for(i=1;i<=n;i++)a[i]=read();
    25         for(m=1;(m<<1)<=n&&a[m]==a[n-m+1];m++);
    26         if((m<<1)>n){printf("%lld
    ",1ll*n*(n+1)>>1);continue;}
    27         
    28         int n1=n-((m-1)<<1);
    29         memset(rest,0,(n+1)<<2),memset(need,0,(n+1)<<2);
    30         for(i=1;i<=n1;i++)rest[b[i]=a[i+m-1]]++;
    31         int odd=0;
    32         for(i=0;i<=n;i++)odd+=rest[i]&1;
    33         if(odd>(n1&1)){puts("0");continue;}
    34         
    35         for(i=n1;i;i--){
    36             rest[b[i]]--,need[b[i]]++;
    37             if((i<<1)<=n1)
    38                 if(b[i]==b[n1-i+1])need[b[i]]-=2;else break;
    39             if((i<<1)==n1+1)need[b[i]]--;
    40             if(need[b[i]]>rest[b[i]])break;
    41         }int L=i;
    42         
    43         memset(rest,0,(n+1)<<2),memset(need,0,(n+1)<<2);
    44         for(i=1;i<=n1;i++)rest[b[i]]++;
    45         for(i=1;i<=n1;i++){
    46             rest[b[i]]--,need[b[i]]++;
    47             if((i<<1)>n1+1)
    48                 if(b[i]==b[n1-i+1])need[b[i]]-=2;else break;
    49             if((i<<1)==n1+1)need[b[i]]--;
    50             if(need[b[i]]>rest[b[i]])break;
    51         }int R=n1-i+1;
    52     //    printf("    m:%d   L:%d  R:%d
    ",m,L,R);
    53         printf("%lld
    ",1ll*m*(m + 2*n1-L-R));
    54     }
    55 }
    View Code
  • 相关阅读:
    IOS中的几种锁(转)
    IOS 主要框架 介绍
    码率bitrate,帧率frame rate,分辨率 (转)
    jupyter notebook 更换主题的方法
    谷歌刚发布的求梯度的工具包-Tangent
    吴恩达深度学习第1课第4周-任意层人工神经网络(Artificial Neural Network,即ANN)(向量化)手写推导过程(我觉得已经很详细了)
    女儿开始bababababa的发声了
    GrideSearchCV 优化算法参数
    修改博客园模板
    Printer for Me
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5950931.html
Copyright © 2011-2022 走看看