Help!
查看原帖
Help!
754311
zhangjiting楼主2024/1/9 17:08

分块,跟 P4145 一个思路。

样例过了但 0pts。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,M=5e2+5;
int block,tot,n,m,flag[M],lt[M],rt[M],a[N],belong[N];
unsigned sum[M];
void build(){
	block=(int)sqrt((double)n);
	tot=n/block;
	if(n%block) tot++;
	for(int i=1;i<=tot;i++){
		lt[i]=(i-1)*block+1;
		rt[i]=i*block;
	}
	rt[tot]=n;
	for(int i=1;i<=n;i++){
		belong[i]=(i-1)/block+1;
		sum[belong[i]]+=a[i];
	}
}
void change(int x,int y,int k){
	if(belong[x]==belong[y]){
		if(flag[belong[x]]==1) return;
		for(int i=x;i<=y;i++){
			if(a[i]!=1){
				sum[belong[x]]-=a[i];
				a[i]=__gcd(a[i],k);
				sum[belong[x]]+=a[i];
			}
		}
		return;
	}
	if(flag[belong[x]]!=1) {
		for(int i=x;i<=rt[belong[x]];i++){
			sum[belong[x]]-=a[i];
			a[i]=__gcd(a[i],k);
			sum[belong[x]]+=a[i];
		}
	}
	if(flag[belong[y]]!=1) {
		for(int i=lt[belong[y]];i<=y;i++){
			sum[belong[y]]-=a[i];
			a[i]=__gcd(a[i],k);
			sum[belong[y]]+=a[i];
		}
	}
	for(int i=belong[x]+1;i<=belong[y]-1;i++){
		if(!flag[i]||k%flag[i]){
			flag[i]=__gcd(flag[i],k);
			if(flag[i]!=1){
				for(int j=lt[i];j<=rt[i];j++){
					if(a[j]!=1){
						sum[i]-=a[j];
						a[j]=__gcd(a[j],k);
						sum[i]+=a[j];
					}
				}
			}
		}
	}
	return;
}
unsigned ask(int x,int y){
	unsigned ans=0;
	if(belong[x]==belong[y]){
		if(flag[belong[x]]!=1){
            for(int i=x;i<=y;i++) ans+=a[i];
            return ans;
        }
        else return y-x+1;
	}
	if(flag[belong[x]]!=1)for(int i=x;i<=rt[belong[x]];i++)ans+=a[i];
	else ans+=rt[belong[x]]-x;
	if(flag[belong[x]]!=1)for(int i=lt[belong[y]];i<=y;i++)ans+=a[i];
	else ans+=y-lt[belong[y]];
	for(int i=belong[x]+1;i<=belong[y]-1;i++){
		if(flag[i]!=1) ans+=sum[i];
		else ans+=block;
	}
	return ans;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	build();
	for(int i=1;i<=m;i++){
		int opt,l,r;
		cin>>opt>>l>>r;
		if(opt==1){
			int x;
			cin>>x;
			change(l,r,x);
		}
		else{
			cout<<ask(l,r)<<endl;
		}
	}
	return 0;
}
2024/1/9 17:08
加载中...