线段树求调
查看原帖
线段树求调
477757
V1mnkE楼主2023/2/10 16:15

rt

#include<bits/stdc++.h>
#define ls o<<1
#define rs o<<1|1
#define int long long
using namespace std;
const int maxn=2e5+5;
const int mod=19260817;
int n,m;
int d[maxn],a[maxn];
struct data{
	int l,r;
	int lcost,rcost,sum;
}t[maxn<<2];
data pushup(data lc,data rc){
	data tmp;
	int l=lc.l,r=rc.r;
	int mid=l+r>>1;
	tmp.lcost=(lc.lcost+rc.lcost+((rc.sum*(d[mid+1]-d[l]))%mod))%mod;
	tmp.rcost=(rc.rcost+lc.rcost+((lc.sum*(d[r]-d[mid]))%mod))%mod;
	tmp.sum=((lc.sum+rc.sum)%mod+mod)%mod;
	tmp.l=l,tmp.r=r;
	return tmp;
}
void build(int o,int l,int r){
	t[o].l=l,t[o].r=r;
	if(l==r){
		t[o].sum=a[l],t[o].lcost=t[o].rcost=0;
		return ;
	}
	int mid=l+r>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	t[o]=pushup(t[ls],t[rs]);
}
data query(int o,int l,int r,int x,int y){
	data res={l,r,0,0,0};
	if(x>y)return res;
//	cout<<1<<endl;
	if(x<=l&&r<=y)return t[o];
	int mid=l+r>>1;
	if(x<=mid)res=pushup(res,query(ls,l,mid,x,y));
	if(y>mid)res=pushup(res,query(rs,mid+1,r,x,y));
	return res;
}
signed main(){
	cin>>n>>m;
	for(int i=2;i<=n;i++){
		cin>>d[i];
		d[i]+=d[i-1];
	}
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]%=mod;
	}
	build(1,1,n);
	while(m--){
		int x,l,r;
		cin>>x>>l>>r;
		if(l>r)swap(l,r);
		if(x<l){
			data ans=query(1,1,n,l,r);
			printf("%d\n",((ans.lcost+ans.sum*((d[l]-d[x])%mod))%mod+mod)%mod);		
		}
		else if(x>r){
			data ans=query(1,1,n,l,r);
			printf("%d\n",((ans.rcost+ans.sum*((d[x]-d[r])%mod))%mod+mod)%mod);	
		}
		else {
			data ans1=query(1,1,n,l,x-1);
			data ans2=query(1,1,n,x+1,r);
			printf("%d\n",((ans1.rcost+ans2.lcost)%mod+mod)%mod);
		}
	}
}

甚至没过样例

2023/2/10 16:15
加载中...