1. 程式人生 > >[NOIP2018校模擬賽]T1聚會 party

[NOIP2018校模擬賽]T1聚會 party

get P20 mem .net 家庭 tchar 我們 圖片 mes

題目鏈接:

聚會

分析:

設每個點到1號點的距離為dist_{i},每個點的權值為x_{i},目標點到1號點的距離為dist,權值為x,那麽對於每一次查詢,我們討論三種情況:

① 目標家庭在區間左邊(x<=l)
如圖所示技術分享圖片

    這種情況下
     ans=sum((dist_{i}-dist)*x_{i])
                         =sum(dist_{i]*x_{i}) - dist*sum(x_{i})

②目標家庭在區間右邊(x>=r)

    容易同理得到
    ans= dist*sum(x_{i})-sum(dist_{i]*x_{i}) 

③目標家庭在區間中間(l<x<r)

    將區間從目標家庭處分開,分別求左右子區間的ans1,ans2,過程同①,②

為了降低時間復雜度,每個點到1號點的距離,每個點的權值,以及前兩項的乘積都用前綴和來存儲,於是我們維護三個前綴和數組——代碼中分別是dist,b,p,這樣對於每次查詢的時間復雜度是O(1)的,總時間復雜度為O(N)。
被坑到的點:
相減的時候可能出現負值,對應的余數也會變成負值,這時候加一個特判

if(ans<0)ans+=mod;

即可。(不加會見祖宗你信嗎)

代碼如下:

#include<bits/stdc++.h>
#define frog 19260817
using namespace std;
inline long long read(){
    int cnt=0,f=1;char c;
    c=getchar();
    while(!isdigit(c)){if(c==‘-‘)f=-1;c=getchar();}
    while(isdigit(c)){cnt=cnt*10+c-‘0‘;c=getchar();}
    return cnt*f;
}
long long n,m,dist[200005],x=0,a,l,r;
long long p[200005],b[200005];
long long ans;
int main(){
    n=read();m=read();
    memset(dist,0,sizeof(dist));
    memset(p,0,sizeof(p));
    memset(b,0,sizeof(b));
    for(register int i=2;i<=n;i++){
        x=read();
        dist[i]=(x+dist[i-1])%frog;
    }
    for(register int i=1;i<=n;i++){
        x=read();
        b[i]=(x+b[i-1])%frog;
        p[i]=(p[i-1]+x*dist[i])%frog;
    }
    for(register int i=1;i<=m;i++){
        a=read();l=read();r=read();
        if(a<=l){
            long long t1=(p[r]-p[l-1])%frog;
            long long t2=((b[r]-b[l-1])*dist[a])%frog;
            ans=(t1-t2)%frog;
        }
        if(a>=r){
            long long t1=(p[r]-p[l-1])%frog;
            long long t2=((b[r]-b[l-1])*dist[a])%frog;
            ans=(t2-t1)%frog;
        }
        if(l<a&&a<r){
            long long t1=(p[a]-p[l-1])%frog;
            long long t2=((b[a]-b[l-1])*dist[a])%frog;
            long long t3=(p[r]-p[a])%frog;
            long long t4=((b[r]-b[a])*dist[a])%frog;
            ans=((t2-t1+t3-t4)%frog)%frog;
        }
        if(ans<0)ans+=frog;
        printf("%lld\n",ans);
    }
    return 0;
}

[NOIP2018校模擬賽]T1聚會 party