笛卡尔树分治+二分 WA on #7求调 悬关
查看原帖
笛卡尔树分治+二分 WA on #7求调 悬关
556975
PNNNN楼主2024/9/10 21:27
#include<bits/stdc++.h>
#define int long long
#define fr first
#define sc second
using namespace std;

inline int gcd(int x,int y){
	return y==0?x:gcd(y,x%y);
}

int n,a[200005],lt[200005],rt[200005],ans;

int st[200005],top;

int f[200005][25][2],lg[200005];

vector <pair<int,int>> vec[200005][2];

inline int read(){
	register int x(0),t(0);
	static char ch=getchar();
	while(!isdigit(ch)){t|=(ch=='-');ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return t?-x:x;
}

signed main(){
	
	n=read(),lg[0]=-1;
	for(int i=1;i<=n;i++){
		a[i]=read();
		f[i][0][0]=f[i][0][1]=a[i];
		lg[i]=lg[i>>1]+1;
	}
	
	st[top=0]=0;
	for(int i=1;i<=n;i++){
		while(top&&a[st[top]]<a[i])top--;
		lt[i]=st[top]+1,st[++top]=i;
	}
	st[top=0]=n+1;
	for(int i=n;i>=1;i--){
		while(top&&a[st[top]]<a[i])top--;
		rt[i]=st[top]-1,st[++top]=i;
	}
	
	for(int j=1;1<<j<=n;j++){
		for(int i=(1<<j);i<=n;i++){
			f[i][j][0]=gcd(f[i][j-1][0],f[i-(1<<j-1)][j-1][0]);
		}
	}
	for(int j=1;1<<j<=n;j++){
		for(int i=1;i+(1<<j)-1<=n;i++){
			f[i][j][1]=gcd(f[i][j-1][1],f[i+(1<<j-1)][j-1][1]);
		}
	}
	
	for(int i=1;i<=n;i++){
		int last,now;
		now=i,last=a[i];
		while(true){
			vec[i][0].push_back({now,last});
			for(int j=lg[now];j>=0&&now>=1;j--){
				if(f[now][j][0]&&f[now][j][0]%last==0){
					now=now-(1<<j);
				}
			}
			if(now<1)break;
			last=gcd(last,f[now][0][0]);
		}
		vec[i][0].push_back({0,0});
		now=i,last=a[i];
		while(true){
			vec[i][1].push_back({now,last});
			for(int j=lg[n-now+1];j>=0&&now<=n;j--){
				if(f[now][j][1]&&f[now][j][1]%last==0){
					now=now+(1<<j);
				}
			}
			if(now>n)break;
			last=gcd(last,f[now][0][0]);
		}
		vec[i][1].push_back({n+1,0});
	}
	
	for(int i=1;i<=n;i++){
		if(i-lt[i]<rt[i]-i){
			for(int j=lt[i];j<=i;j++){
				int pos;
				for(int p=0;p<vec[j][1].size();p++){
					pair<int,int> v=vec[j][1][p];
					if(v.fr<=i){
						pos=p;
					}else break; 
				}
				for(int p=pos;p<vec[j][1].size();p++){
					pair<int,int> v=vec[j][1][p];
					if(v.fr>rt[i])break;
					ans+=v.sc*(min(vec[j][1][p+1].fr-1,rt[i])-max(i,v.fr)+1)*a[i];
				}
			}
		}else{
			for(int j=rt[i];j>=i;j--){
				int pos;
				for(int p=0;p<vec[j][0].size();p++){
					pair<int,int> v=vec[j][0][p];
					if(v.fr>=i){
						pos=p;
					}else break; 
				}
				for(int p=pos;p<vec[j][0].size();p++){
					pair<int,int> v=vec[j][0][p];
					if(v.fr<lt[i])break;
					ans+=v.sc*(min(i,v.fr)-max(vec[j][0][p+1].fr+1,lt[i])+1)*a[i];
				}
			}
		}
	}
	cout<<ans;
	
	return 0;
}
2024/9/10 21:27
加载中...