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;
}
posted @ 2019-02-04 10:23  y2823774827y  阅读(193)  评论(0编辑  收藏  举报