• 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();}
    
  • 相关阅读:
    c#获得本月份是本季度的第几个月
    C#如何把月份转换成季度
    日本是如何处理地沟油的?
    惊艳的“学长帮我修电脑” VS “我想作你的下一行code”
    居然有人用腾讯QQ的申诉,来找回被盗的奇瑞QQ汽车[有图有真相]
    你长得够安全吗?
    这一刻我被深深地震精了![视频]Visual Studio最新"煽情"广告 让我做你下一行code
    打击地球人专用图
    ReportViewer的动态绑定
    纯天然的野菜居然会致癌?
  • 原文地址:https://www.cnblogs.com/yspm/p/12945663.html
Copyright © 2020-2023  润新知