1. 程式人生 > >【NOIP模擬】聚會

【NOIP模擬】聚會

                                                     聚會

描述

在成都的一條街道上,一共有 NN戶人家,每個家庭有 XiXi 個人,他們和諧的生活在 一起,作為全國和諧街道,他們經常會小範圍組織活動,每次活動會選擇一戶作為聚點, 並要求某些家庭參加,為了方便通知,村長每次邀請位置連續的家庭。因為每戶人數不 同,每個家庭之間有一定距離,村長希望你計算出每次邀請的家庭的移動代價。第 ii個家 庭移動到家庭 jj的代價是:Xi∗dis(i,j)Xi∗dis(i,j)

dis(i,j)dis(i,j)表示ii 到jj的距離,村長一共安排了 mm 次聚會,每次邀請[Li,Ri][Li,Ri]的家庭參加

輸入

第一行兩個數表示 n,m

第二行 n-1 個數,第 i 個數表示第 i 個家庭與第 i+1 個家庭的距離 Di

第三行 n 個數,表示每個家庭的人數 Xi

之後 m 行每行三個數 x l r,表示查詢要把區間 [l,r]的家庭移動到 x 點的代價和

輸出

對於每個詢問輸出一個數表示答案,對 19260817 取模

樣例輸入

5 5 2 3 4 5 1 2 3 4 5 1 1 5 3 1 5 2 3 3 3 3 3 1 5 5

樣例輸出

125 72 9 0 70

提示

對於 30%的資料, n,m≤1000

對於另外 20%的資料,所有家庭間的距離都為 1

對於另外 20%的資料,所有家庭人數都為 1

對於 100%的資料 , n,m≤200000;Xi,Di <=2*10^9

程式碼:  

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int mod=19260817;
const int Max=200005;
int n,m,ans,pos[Max],num[Max],sum1[Max],sum2[Max];

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}
inline void print(int x)
{
	if(x>9) print(x/10);
	putchar('0'+x%10);
}

inline int calc1(int x,int l,int r){return ((sum2[r]-sum2[l-1])%mod+mod)%mod-x%mod*((sum1[r]-sum1[l-1])%mod+mod)%mod;}
inline int calc2(int x,int l,int r){return x%mod*((sum1[r]-sum1[l-1])%mod+mod)%mod-((sum2[r]-sum2[l-1])%mod+mod)%mod;}
inline void solve()
{
	while(m--)
	{
	  int x=get_int(),l=get_int(),r=get_int();
	  if(x<l) ans=calc1(pos[x],l,r)%mod;
	  else if(x>r) ans=calc2(pos[x],l,r)%mod;
	  else ans=(calc1(pos[x],x,r)+calc2(pos[x],l,x))%mod;
	  print((ans%mod+mod)%mod),putchar('\n');
	}
}

signed main()
{
	n=get_int(),m=get_int();
	for(int i=2;i<=n;i++) pos[i]=get_int();
	for(int i=2;i<=n;i++) pos[i]=(pos[i]+pos[i-1])%mod;
	for(int i=1;i<=n;i++) sum1[i]=num[i]=get_int(),sum2[i]=(num[i]*pos[i])%mod;
	for(int i=2;i<=n;i++) sum1[i]=(sum1[i]+sum1[i-1])%mod,sum2[i]=(sum2[i]+sum2[i-1])%mod;
	solve();
	return 0;
}