线段树求调
查看原帖
线段树求调
520056
luoyx楼主2022/10/3 19:54

没想到贪心,就打了一个暴力。但toolarge好像出问题了。

#include <bits/stdc++.h>
#define lc p*2
#define rc p*2+1
#define int long long
using namespace std;
int n,q;
const int N=2e5+5;
int a[N];
int opt,x,k,l,r;
int f[20];
long long too_large=(1<<30);
struct node{
	long long sum,lt=1,lt2=1;
}tr[N<<2];
struct node2{
	long long sum,lt;
}tr2[N<<2];
void init(){
	f[0]=1;
	for(int i=1;i<=18;i++){
		f[i]=f[i-1]*2;
	}
}
void push_up(int p){
	if(tr[lc].sum==-1||tr[rc].sum==-1) tr[p].sum=-1;
	else if(tr[lc].sum>too_large/tr[rc].sum) tr[p].sum=-1;
	else if(tr[lc].sum==too_large/tr[rc].sum&&too_large%tr[rc].sum!=0) tr[p].sum=-1;
	else tr[p].sum=tr[lc].sum*tr[rc].sum;
}
void build(int p,int l,int r){
	if(l==r){
		tr[p].sum=abs(a[l]);
		return ;
	}
	int m=l+r>>1;
	build(lc,l,m);
	build(rc,m+1,r);
	push_up(p);
}
void push_up2(int p){
	tr2[p].sum=tr2[lc].sum+tr2[rc].sum;
}
void build2(int p,int l,int r){
	if(l==r){
		tr2[p].sum=a[l]<0?1:0;
		return ;
	}
	int m=l+r>>1;
	build2(lc,l,m);
	build2(rc,m+1,r);
	push_up2(p);
}
/*
void push_down(int p,int l,int r){
	if(tr[lc].sum>0){
		tr[lc].sum*=tr[p].lt2;
		tr[lc].sum/=tr[p].lt;
	}
	if(tr[rc].sum>0){
		tr[rc].sum*=tr[p].lt2;
		tr[rc].sum/=tr[p].lt;
	}
	tr[p].lt=tr[p].lt2=1;
}
*/
void upd_chu(int p,int l,int r,int ul,int ur,int k){
	if(l>=ul&&r<=ur){
		if(tr[p].sum>0) tr[p].sum/=k;
		tr[p].lt*=k;
		return ;
	}
	int m=l+r>>1;
	if(m>=ul) upd_chu(lc,l,m,ul,ur,k);
	if(m+1<=ur) upd_chu(rc,m+1,r,ul,ur,k);
	push_up(p);
}
void upd_cheng(int p,int l,int r,int ul,int ur,int k){
	if(l>=ul&&r<=ur){
		if(tr[p].sum>0){
			if(k<too_large/tr[p].sum) tr[p].sum*=k;
			else if(k==too_large/tr[p].sum&&too_large%tr[p].sum==0) tr[p].sum*=k;
			else tr[p].sum=-1;
		}
		tr[p].lt2*=k;
		return ;
	}
	int m=l+r>>1;
	if(m>=ul) upd_cheng(lc,l,m,ul,ur,k);
	if(m+1<=ur) upd_cheng(rc,m+1,r,ul,ur,k);
	push_up(p);
}
void upd2(int p,int l,int r,int ul,int ur,int k){
	if(l>=ul&&r<=ur){
		tr2[p].sum+=k*(r-l+1);
		tr2[p].lt+=k;
		return ;
	}
	int m=l+r>>1;
	if(m>=ul) upd2(lc,l,m,ul,ur,k);
	if(m+1<=ur) upd2(rc,m+1,r,ul,ur,k);
	push_up2(p);
}
long long query(int p,int l,int r,int ql,int qr){
	if(l>=ql&&r<=qr) return tr[p].sum;
	int m=l+r>>1;
	long long ans=1;
	if(m>=ql){
		ans*=query(lc,l,m,ql,qr);
		if(ans==-1) return ans;
	}
	if(m+1<=qr){
    	int gj=query(rc,m+1,r,ql,qr);
		if(gj<too_large/ans) ans*=gj;
		else if(gj==too_large/ans&&too_large%ans==0) ans*=gj;
		else ans=-1;
		if(ans<0) return -1;
	}
	return ans;
}
long long query2(int p,int l,int r,int ql,int qr){
	if(l>=ql&&r<=qr) return tr2[p].sum;
	int m=l+r>>1;
	int ans=0;
	if(m>=ql) ans+=query2(lc,l,m,ql,qr);
	if(m+1<=qr) ans+=query2(rc,m+1,r,ql,qr);
	return ans;
}
signed main(){
	//freopen("T1ex2.in","r",stdin);
	//freopen("18.out","w",stdout);
	cin>>n>>q;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	build(1,1,n);
	build2(1,1,n);
	init();
	while(q--){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d",&x,&k);
			if(k<0){
				if(a[x]>0) upd2(1,1,n,x,x,1);
			}
			if(k>0){
				if(a[x]<0) upd2(1,1,n,x,x,-1);
			}
			upd_chu(1,1,n,x,x,abs(a[x]));
			upd_cheng(1,1,n,x,x,abs(k));
			a[x]=k;
		}
		else{
			scanf("%d%d",&l,&r);
			if(query2(1,1,n,l,r)%2==0){
				int sum=query(1,1,n,l,r);
				if(sum==-1) printf("Too large\n");
				else printf("%lld\n",sum);
			}
			else if(l==r){
				cout<<1<<endl;
			}
			else{
				int step=l,com=query2(1,1,n,l,r),sum,sum2;
				for(int i=18;i>=0;i--){
					if(step+f[i]<=r&&query2(1,1,n,step+f[i],r)==com)
						step+=f[i];
				}
				step++;
				sum=query(1,1,n,step,r);
				step=r;
				for(int i=18;i>=0;i--){
					if(step-f[i]>=l&&query2(1,1,n,l,step-f[i])==com)
						step-=f[i];
				}
				step--;
				sum2=query(1,1,n,l,step);
				if(sum==-1||sum2==-1){
					printf("Too large\n");
				}
				else printf("%lld\n",max(sum,sum2));
			}
		}
	}
}
2022/10/3 19:54
加载中...