Luogu6080 [USACO05DEC]Cow Patterns G
Posted yspm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu6080 [USACO05DEC]Cow Patterns G相关的知识,希望对你有一定的参考价值。
Description
link 其实就是 (bzoj1461)
一般的 (kmp) 我们求的是相等的部分
现在给定数字串,求大小关系相等的个数
Solution
其实还是 (kmp)
改变的地方我们把那个判断相等改成用树状数组
具体就是看值域前面的数的个数
求 (nxt) 比较简单,根据 (kmp) 的原理来的
每次跳的时候把原来的值都得清空掉
(不太好写,细节有点点多)
然后查询也是板子套树状数组
这里我发现网上使用一棵 (BIT) 的做法无法通过洛谷的数据
然后去找到了一份用两个的
(一个 (BIT) 的正确性确实……其实是他们没有清空完……)
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mp make_pair
#define pii pair<int,int>
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
return res*f;
}
const int N=5e5+10;
int n,m,s,a[N],b[N],nxt[N],l[N],e[N],ans[N],cnt;
struct BIT{
int c[N];
inline int lowbit(int x){return x&(-x);}
inline void add(int x,int y){for(;x<=s;x+=lowbit(x)) c[x]+=y; return ; }
inline int ask(int x){int res=0; for(;x;x-=lowbit(x)) res+=c[x]; return res;}
inline void clear(){return memset(c,0,sizeof(c)),void();}
}t1,t2;
inline pii get1(int p){return mp(t1.ask(p),t1.ask(p-1));}
inline pii get2(int p){return mp(t2.ask(p),t2.ask(p-1));}
signed main()
{
// freopen("1.in","r",stdin);
n=read(); m=read(); s=read();
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1;i<=m;++i) b[i]=read();
t1.clear(); t2.clear();
for(int i=2,j=0;i<=m;++i)
{
while(j)
{
pii x=get1(b[j+1]),y=get2(b[i]);
if(x==y) break;
for(int k=nxt[j]+1;k<=j;++k) t1.add(b[k],-1);
for(int k=i-j;k<i-nxt[j];++k) t2.add(b[k],-1);
j=nxt[j];
}
pii x=get1(b[j+1]),y=get2(b[i]);
if(x==y) t1.add(b[j+1],1),t2.add(b[i],1),++j;
nxt[i]=j;
}
t1.clear(); t2.clear();
for(int i=1,j=0;i<=n;++i)
{
while(j)
{
pii x=get1(b[j+1]),y=get2(a[i]);
if(x==y) break;
for(int k=nxt[j]+1;k<=j;++k) t1.add(b[k],-1);
for(int k=i-j;k<i-nxt[j];++k) t2.add(a[k],-1);
j=nxt[j];
}
pii x=get1(b[j+1]),y=get2(a[i]);
if(x==y) t1.add(b[j+1],1),t2.add(a[i],1),++j;
if(j==m)
{
ans[++cnt]=i-m+1;
for(int k=nxt[j]+1;k<=j;++k) t1.add(b[k],-1);
for(int k=i-j+1;k<=i-nxt[j];++k) t2.add(a[k],-1);
j=nxt[j];
}
}
printf("%lld
",cnt); for(int i=1;i<=cnt;++i) printf("%lld
",ans[i]);
return 0;
}
}
signed main(){return yspm::main();}
以上是关于Luogu6080 [USACO05DEC]Cow Patterns G的主要内容,如果未能解决你的问题,请参考以下文章
Luogu P3000 [USACO10DEC]牛的健美操Cow Calisthenics
[Luogu2870] [USACO07DEC]最佳牛线Best Cow Line(贪心+后缀数组)
洛谷 2966 [USACO09DEC]牛收费路径Cow Toll Paths
P7990-[USACO21DEC]Closest Cow Wins S堆,贪心