线段树 15pts求调
查看原帖
线段树 15pts求调
797897
_QyGyQ_楼主2024/3/19 13:37
#include<bits/stdc++.h>
#define lc(p) (p<<1)
#define rc(p) (p<<1|1) 
using namespace std;
const int N=1e6+7;
using ll=long long;
vector<int>v[N];
int tree[N<<2];
int a[N];
int n,m;
vector<vector<int>::iterator>IT;
void push_up(int p){
	tree[p]=tree[lc(p)]+tree[rc(p)];
}
void build(int p,int pl,int pr){
	if(pl==pr){
		tree[p]=a[pl];
		return ;
	}
	int mid=pl+pr>>1;
	build(lc(p),pl,mid);
	build(rc(p),mid+1,pr);
	push_up(p);
}
void work(int x,int id){
	for(int i=1;i*i<=id;i++){
		if(id%i==0){
			v[i].push_back(x);
			if(id/i^i){
				v[id/i].push_back(x);
			}
		}
	}
}
void change(int i,int p,int pl,int pr,int d){
	if(pl==pr){
		tree[p]-=d;
		return ;
	}
	int mid=pl+pr>>1;
	if(i<=mid) change(i,lc(p),pl,mid,d);
	else change(i,rc(p),mid+1,pr,d);
	push_up(p);
}
int query(int L,int R,int p,int pl,int pr){
	if(L<=pl&&pr<=R){
		return tree[p];
	}
	int mid=pl+pr>>1;
	int res=0;
	if(L<=mid) res+=query(L,R,lc(p),pl,mid);
	if(R>mid) res+=query(L,R,rc(p),mid+1,pr);
	return res;
}
void update(int L,int R,int k){
	if(k==1||v[k].empty()) return ;
	vector<int>::iterator pl=lower_bound(v[k].begin(),v[k].end(),L);
	vector<int>::iterator pr=upper_bound(v[k].begin(),v[k].end(),R);
	if(pl==v[k].end()) return ;
	IT.clear();
	for(auto it=pl;it!=pr;it++){
		if(a[*it]%k==0){
			int now=a[*it];
			int sum=now/k;
			change(*it,1,1,n,a[*it]-a[*it]/k);
			a[*it]/=k;
			now=a[*it];
			if(now%k){
				IT.push_back(it);
			}
		}
	}
	for(int i=IT.size()-1;i>0;i--){
		v[k].erase(IT[i]);
	}
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		work(i,a[i]);
	}
	build(1,1,n);
	while(m--){
		int op,l,r;
		cin>>op>>l>>r;
		if(op==1){
			int x;
			cin>>x;
			update(l,r,x);
		}
		else cout<<query(l,r,1,1,n)<<"\n";
	}
	return 0;
}

2024/3/19 13:37
加载中...