P3794 签到题IV

题目

P3794 签到题IV
来切道水题放松一下吧

做法

或是单调不下降的,\(gcd\)是单调不上升的

\(a_i≤5×10^5\)分成权值不同的块数应该很小,所以随便乱搞就出来了

My complete code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn=1e6;
LL t1,t2,n,k,ans;
LL a[maxn],q1[maxn],q2[maxn],num1[maxn],num2[maxn],q[maxn],num[maxn];
LL Gcd(LL x,LL y){
    while(y){
        LL tmp(y);
        y=x%y,x=tmp;
    }return x;
}
inline void Update1(LL x){
    for(LL i=1;i<=t1;++i) q1[i]=Gcd(q1[i],x);
    q1[++t1]=x,num1[t1]=1;
    LL cnt(0);
    for(LL i=1;i<=t1;++i)
        if(i==1 || q1[i]!=q[cnt]) q[++cnt]=q1[i],num[cnt]=num1[i];
        else num[cnt]+=num1[i];
    t1=cnt;
    for(LL i=1;i<=t1;++i) q1[i]=q[i],num1[i]=num[i];
}
inline void Update2(LL x){
    for(LL i=1;i<=t2;++i) q2[i]|=x;
    q2[++t2]=x,num2[t2]=1;
    LL cnt(0);
    for(LL i=1;i<=t2;++i)
        if(i==1 || q2[i]!=q[cnt]) q[++cnt]=q2[i],num[cnt]=num2[i];
        else num[cnt]+=num2[i];
    t2=cnt;
    for(LL i=1;i<=t2;++i) q2[i]=q[i],num2[i]=num[i];
}
inline void Solve(){
    LL i(1),j(1),na(num1[1]),nb(num2[1]);
    while(i<=t1){
        LL d(min(na,nb));
        if((q1[i]^q2[j])==k) ans+=d;
        na-=d,nb-=d;
        if(!na) na=num1[++i];
        if(!nb) nb=num2[++j];
    }
}
int main(){
    cin>>n>>k;
    for(LL i=1;i<=n;++i){
        cin>>a[i];
        Update1(a[i]),Update2(a[i]);
        Solve();
    }
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/y2823774827y/p/10351496.html