【NOIP模擬】聚會
阿新 • • 發佈:2018-12-13
聚會
描述
在成都的一條街道上,一共有 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; }