P9453 [ZSHOI-R1] 有效打击 题解

· · 题解

P9453 [ZSHOI-R1] 有效打击 题解

题目分析

#include<iostream>
#include<cmath>
#define int long long
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch<='9'&&ch>='0'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
const int maxn=5e6+100;
struct node {
    int x,v;
    double y;
}a[maxn],b[maxn];
double h=1e-6;
int n,m;
bool cal(node e,node f,int ai,int bi){//比较两段是否相等
    if((ai==1||bi==1||bi==m)&&e.x==f.x) return 1;
    else if(e.x==f.x&&abs(e.y-f.y)<=h) return 1; 
    else return 0;
}
int gcd(int a,int b){
    if(a>b)swap(a,b);
    if(!a||!b) return a+b;
    return gcd(b%a,a);
}
int kmp[maxn];
int j;
int ans;
signed main(){
    int nn=read(),mm=read();
    for(int i=1;i<=nn;i++) {
        int p=read();
        if(a[n].x!=p) a[++n].x=p,a[n].v=1;
        else a[n].v++;
    }
    for(int i=1;i<=mm;i++) {
        int p=read();
        if(b[m].x!=p) b[++m].x=p,b[m].v=1;
        else b[m].v++;

    }
    if(m==1){
        for(int i=1;i<=n;i++){
            if(a[i].x==b[m].x) ans+=a[i].v*(a[i].v+1)/2;
        }
        cout<<ans<<endl;
    }
    else if(m==2){
        int k=gcd(b[1].v,b[2].v);
        b[1].v=b[1].v/k,b[2].v=b[2].v/k;
        for(int i=1;i<=n;i++){
            if(a[i].x==b[2].x&&a[i-1].x==b[1].x)ans+=min(a[i].v/b[2].v,a[i-1].v/b[1].v);
        }
        cout<<ans<<endl; 
    }
    else {
        for(int i=2;i<=n;i++) a[i].y=double(a[i].v)/double(a[i-1].v);
        for(int i=2;i<=m;i++) b[i].y=double(b[i].v)/double(b[i-1].v);
        int la=n,lb=m;
            for(int i=2;i<=lb;i++){
            while(j&&!cal(b[i],b[j+1],i,j+1)){
                j=kmp[j];
            }
            if(cal(b[i],b[j+1],i,j+1)){
                j++;
                kmp[i]=j;
            }
        }
        j=0;
        for(int i=1;i<=la;i++){
            while(j&&!cal(a[i],b[j+1],i,j+1)){
                j=kmp[j];
            }
            if(cal(a[i],b[j+1],i,j+1)){
                j++;
            }
            if(j==lb){
                ans++;
                j=kmp[j];   
            }
        }
        cout<<ans<<endl;
    }
}