luogu P3932 浮遊大陸的68號島
阿新 • • 發佈:2018-10-04
lib while inf read efi 簡單的 區間 fin 由於
有一天小妖精們又在做遊戲。這個遊戲是這樣的。
妖精倉庫的儲物點可以看做在一個數軸上。每一個儲物點會有一些東西,同時他們之間存在距離。
每次他們會選出一個小妖精,然後剩下的人找到區間[l,r]儲物點的所有東西,清點完畢之後問她,把這個區間內所有儲物點的東西運到另外一個倉庫的代價是多少?
比如儲物點i有x個東西,要運到儲物點jj,代價為 x*dist(i,j)
dist就是倉庫間的距離。
當然啦,由於小妖精們不會算很大的數字,因此您的答案需要對19260817取模
輸入輸出格式
輸入格式:
第一行兩個數表示n,m
第二行n-1個數,第ii個數表示第ii個儲物點與第i+1個儲物點的距離
第三行n個數,表示每個儲物點的東西個數
之後m行每行三個數x l r
表示查詢要把區間[l,r]儲物點的物品全部運到儲物點x的花費
輸出格式:
對於每個詢問輸出一個數表示答案
【分析】
關於今天考試找了個題練練手……
沒想到比考試還簡單 連個修改都沒有
和考試那個題的區別在於多了相鄰點之間的距離dist
推一下每個詢問的答案
就是 ∑(i=l~r)a[i] * abs(d[i]-d[x])
化簡一下就是 abs(∑(i=l~r)(a[i]*d[x]) - ∑(i=l~r)(a[i]*d[i]))
然後a[i]*d[i]可以預處理出來區間和 正負也顯然分成x左右就解決了
總之還是比較簡單的
(如果帶修改樹狀數組維護一下?)
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #define rep(i,a,n) for(int i = a;i <= n;i++) 6 #define per(i,n,a) for(int i = n;i >= a;i--) 7 #define inf 2147483647 8 using namespace std; 9 typedef long long ll; 10 ll read() {11 ll as = 0,fu = 1; 12 char c = getchar(); 13 while(c < ‘0‘ || c > ‘9‘) { 14 if(c == ‘-‘) fu = -1; 15 c = getchar(); 16 } 17 while(c >= ‘0‘ && c <= ‘9‘) { 18 as = as * 10 + c - ‘0‘; 19 c = getchar(); 20 } 21 return as * fu; 22 } 23 const int mod = 19260817; 24 const int N = 200006; 25 //head 26 ll n,m; 27 ll a[N],d[N]; 28 ll sa[N],mlt[N]; 29 ll calc(int l,int r,int x,bool op) { 30 if(l > r) return 0; 31 ll tmp1 = (sa[r] - sa[l-1]) % mod + mod; 32 tmp1 = tmp1 * d[x] % mod; 33 ll tmp2 = (mlt[r] - mlt[l-1]) % mod + mod; 34 if(op) swap(tmp1,tmp2); 35 return ((tmp1-tmp2)%mod+mod)%mod; 36 } 37 38 int main() { 39 n = read(); 40 m = read(); 41 rep(i,2,n) { 42 d[i] = (d[i-1] + read()) % mod; 43 } 44 rep(i,1,n) { 45 a[i] = read() % mod; 46 sa[i] = (sa[i-1] + a[i]) % mod; 47 mlt[i] = (mlt[i-1] + a[i] * d[i]) % mod; 48 } 49 rep(i,1,m) { 50 int x = read(),l = read(),r = read(); 51 ll ansl = calc(l,min(x-1,r),x,0); 52 ll ansr = calc(max(l,x+1),r,x,1); 53 printf("%lld\n",(ansl+ansr) % mod); 54 } 55 return 0; 56 }
OK啦
luogu P3932 浮遊大陸的68號島