zoukankan      html  css  js  c++  java
  • NOIP 考前 KMP练习

    BZOJ 1461 && BZOJ 1729

    KMP+BIT

    一看就是字符串匹配但是不同的是要按照每个字符的排名情况。

    首先对于数字x的排名,那么要判断x前小于x的数的个数,和x前小于等于x的数的个数,这两个都相等才相等。因为会有数字会有重复的.

    然后可以先预处理出字串的每个数字的排名,这样就不需要两个BIT了。最后按照KMP的思路做就可以了.

     1 #include <cstdio>
     2 #include <cstring>
     3 const int MaxN=500100;
     4 const int MaxS=10010;
     5 int a[MaxN],b[MaxN],Rk1[MaxN],Rk2[MaxN],Ans[MaxN],tot,n,k,s,P[MaxN];
     6 int c[MaxS];
     7 inline int Lowbit(int x) {return x&-x;}
     8 inline void Add(int x,int d)
     9 {for (int i=x;i<=s;i+=Lowbit(i)) c[i]+=d;}
    10 inline int Query(int x)
    11 {
    12     int Ret=0;
    13     for (int i=x;i;i-=Lowbit(i)) Ret+=c[i];
    14     return Ret;
    15 }
    16 int main()
    17 {
    18     scanf("%d%d%d",&n,&k,&s);
    19     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    20     for (int i=1;i<=k;i++)
    21     {
    22         scanf("%d",&b[i]); Add(b[i],1);
    23         Rk1[i]=Query(b[i]),Rk2[i]=Query(b[i]-1);
    24     }
    25     memset(c,0,sizeof(c)); int j=0;
    26     for (int i=2;i<=k;i++)
    27     {
    28         Add(b[i],1);
    29         while (j && ((Query(b[i])!=Rk1[j+1]) || (Query(b[i]-1)!=Rk2[j+1])))
    30         {
    31             for (int l=i-j;l<i-P[j];l++) Add(b[l],-1);
    32             j=P[j];
    33         }
    34         if ((Query(b[i])==Rk1[j+1]) && (Query(b[i]-1)==Rk2[j+1])) j++;
    35         P[i]=j;
    36     }
    37     memset(c,0,sizeof(c)); j=0;
    38     for (int i=1;i<=n;i++)
    39     {
    40         Add(a[i],1);
    41         while (j && (Query(a[i])!=Rk1[j+1] || Query(a[i]-1)!=Rk2[j+1])) 
    42         {
    43             for (int l=i-j;l<i-P[j];l++) Add(a[l],-1);
    44             j=P[j];
    45         }
    46         if (Query(a[i])==Rk1[j+1] && Query(a[i]-1)==Rk2[j+1]) j++;
    47         if (j==k)
    48         {
    49             Ans[++tot]=i-j+1;
    50             for (int l=i-j+1;l<=i-P[j];l++) Add(a[l],-1);
    51             j=P[j];
    52         }
    53     }
    54     printf("%d
    ",tot);
    55     for (int i=1;i<=tot;i++) printf("%d
    ",Ans[i]);
    56     return 0;
    57     
    58 }
    双倍经验
  • 相关阅读:
    VS头部自动注释
    JSONP跨域实现
    Chosen:Select 选择框的华丽变身
    Android NFC 整理
    Android Activity生命周期(转)
    eclipse svn 相关
    初学Java web(转)
    Java 定时任务(转)
    声音
    (转)关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/6022766.html
Copyright © 2011-2022 走看看