• poj3167


    这道题是一道kmp的扩展版的好题
    一串匹配一串很容易想到kmp,但是这里的匹配要求的是两个串的名次相同
    显然名次是会变的,为了方便,我们可以换一种表达
    对于两个等长的串的相同位置,名次相等就是在它之前比它小的数的个数一样,和它相等的数的个数一样
    这个我们可以用树状数组维护一下(当然暴力好像也行)
    然后匹配就行了

     1 var ans,a,b,sal,eq:array[0..100010] of longint;
     2     next:array[0..30010] of longint;
     3     c:array[0..30] of longint;
     4     tot,k,n,m,s,i,j:longint;
     5 
     6 function lowbit(x:longint):longint;
     7   begin
     8     exit(x and (-x));
     9   end;
    10 
    11 procedure work(x,p:longint);
    12   begin
    13     while x<=s do
    14     begin
    15       inc(c[x],p);
    16       x:=x+lowbit(x);
    17     end;
    18   end;
    19 
    20 function ask(x:longint):longint;
    21   begin
    22     ask:=0;
    23     while x>0 do
    24     begin
    25       ask:=ask+c[x];
    26       x:=x-lowbit(x);
    27     end;
    28   end;
    29 
    30 begin
    31   readln(n,m,s);
    32   for i:=1 to n do
    33     readln(a[i]);
    34   for i:=1 to m do   //预处理
    35   begin
    36     readln(b[i]);
    37     work(b[i],1);
    38     sal[i]:=ask(b[i]-1);
    39     eq[i]:=ask(b[i]);
    40   end;
    41   fillchar(c,sizeof(c),0);
    42   i:=1;
    43   j:=0;
    44   next[1]:=0;
    45   while i<=m do
    46   begin
    47     if (j=0) or (ask(b[i]-1)=sal[j]) and (ask(b[i])=eq[j]) then
    48     begin
    49       inc(i);
    50       inc(j);
    51       next[i]:=j;
    52       if i>m then break;
    53       work(b[i],1);
    54     end
    55     else begin
    56       for k:=i-j+1 to i-next[j] do  // 保证匹配的串位置一样
    57         work(b[k],-1);
    58       j:=next[j];
    59     end;
    60   end;
    61   fillchar(c,sizeof(c),0);
    62   i:=1;
    63   j:=1;
    64   work(a[1],1);
    65   while (i<=n) do
    66   begin
    67     if (j=0) or (ask(a[i]-1)=sal[j]) and (ask(a[i])=eq[j]) then
    68     begin
    69       inc(i);
    70       inc(j);
    71       if i<=n then
    72         work(a[i],1);
    73     end
    74     else begin
    75       for k:=i-j+1 to i-next[j] do
    76         work(a[k],-1);
    77       j:=next[j];
    78     end;
    79     if j>m then  //注意这里要找出的是所有答案
    80     begin
    81       for k:=i-m to i-next[j] do
    82         work(a[k],-1);
    83       inc(tot);
    84       ans[tot]:=i-m;
    85       j:=next[j];
    86     end;
    87   end;
    88   writeln(tot);
    89   for i:=1 to tot do
    90     writeln(ans[i]);
    91 end.
    View Code
  • 相关阅读:
    值得学习的东西
    【单调队列】转载
    dom基础3 — 简易版template.js
    js基础6 — 数组对象
    js基础6 — 字符串基本操作
    js基础5 — 将十六进制颜色转为rgba()
    js基础4 — 数组操作
    placeholer属性修改
    clipboard.js实现复制到剪切板
    JS 获取指定日期在当年的第几周
  • 原文地址:https://www.cnblogs.com/phile/p/4473144.html
Copyright © 2020-2023  润新知