luogu3932 浮游大陆的68号岛

版权声明:辣鸡蒟蒻的blog https://blog.csdn.net/elijahqi/article/details/80344746

http://www.elijahqi.win/archives/1328
题目背景

大样例下发链接: https://pan.baidu.com/s/1nuVpRS1 密码: sfxg

浮游大陆的68号岛,位于浮游大陆的边境地带。平时很少有人造访。

岛上被浓厚的森林覆盖。

在这座边境地区不起眼的浮游岛上,建立着神秘的”兵器“管理仓库——妖精仓库。
题目描述

妖精仓库里生活着黄金妖精们,她们过着快乐,却随时准备着迎接死亡的生活。

换用更高尚的说法,是随时准备着为这个无药可救的世界献身。

然而孩子们的生活却总是无忧无虑的,幼体的黄金妖精们过着天真烂漫的生活,自然也无暇考虑什么拯救世界之类的重任。

有一天小妖精们又在做游戏。这个游戏是这样的。

妖精仓库的储物点可以看做在一个数轴上。每一个储物点会有一些东西,同时他们之间存在距离。

每次他们会选出一个小妖精,然后剩下的人找到区间[l,r][l,r][l,r]储物点的所有东西,清点完毕之后问她,把这个区间内所有储物点的东西运到另外一个仓库的代价是多少?

比如储物点iii有xxx个东西,要运到储物点jjj,代价为

x×dist(i,j)x \times \mathrm{dist}( i , j )x×dist(i,j)

dist就是仓库间的距离。

当然啦,由于小妖精们不会算很大的数字,因此您的答案需要对19260817取模。

输入输出格式

输入格式:

第一行两个数表示n,mn,mn,m

第二行n−1n-1n−1个数,第iii个数表示第iii个储物点与第i+1i+1i+1个储物点的距离

第三行nnn个数,表示每个储物点的东西个数

之后mmm行每行三个数x l r

表示查询要把区间[l,r][l,r][l,r]储物点的物品全部运到储物点x的花费

输出格式:

对于每个询问输出一个数表示答案
输入输出样例

输入样例#1:

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

输出样例#1:

125
72
9
0
70

说明

对于30%的数据,n,m≤1000n , m \le 1000n,m≤1000

对于另外20%的数据,所有储物点间的距离都为1

对于另外20%的数据,所有储物点的物品数都为1

对于100%的数据 ,n,m≤200000;ai,bi<=2⋅109 n , m \le 200000 ; a_i , b_i <= 2\cdot 10^9n,m≤200000;ai​,bi​<=2⋅109

类似锯木厂选址那题的预处理而已 将距离和花费都做前缀和累加 cost1表示1~i都运往i的花费是多少 cost2同理 然后就可以分类讨论通过加加减减得出结果锯木厂选址

#include<cstdio>
#define mod 19260817
#define N 220000
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0;char ch=gc();
    while (ch<'0'||ch>'9') ch=gc();
    while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
    return x;
}
long long sigma_weigh2[N],sigma_weigh1[N],sigma_dis1[N],sigma_dis2[N],ans,cost1[N],cost2[N];
int x,l,r,n,m,dis[N],weigh[N];
int main(){
    freopen("13375.in","r",stdin);
    freopen("ex.out","w",stdout);
    n=read();m=read();
    for (int i=1;i<n;++i) dis[i]=read(),sigma_dis1[i+1]=(sigma_dis1[i]+dis[i])%mod;
    for (int i=1;i<=n;++i) weigh[i]=read(),sigma_weigh1[i]=(sigma_weigh1[i-1]+weigh[i])%mod;
    for (int i=n;i>=1;--i) sigma_weigh2[i]=(sigma_weigh2[i+1]+weigh[i])%mod;
    for (int i=n;i>1;--i) sigma_dis2[i-1]=(sigma_dis2[i]+dis[i-1])%mod;
    for (int i=1;i<=n;++i) cost1[i]=(cost1[i-1]+sigma_weigh1[i-1]*dis[i-1]%mod)%mod;
    for (int i=n;i>=1;--i) cost2[i]=(cost2[i+1]+sigma_weigh2[i+1]*dis[i]%mod)%mod;
    for (int i=1;i<=m;++i){
        x=read();l=read();r=read();ans=0;
        if (x>=l&&x<=r){
            (ans+=cost1[x]-cost1[l-1]-sigma_weigh1[l-1]*((sigma_dis1[x]-sigma_dis1[l-1]+mod)%mod)%mod)%=mod;ans+=mod;ans%=mod;
            (ans+=cost2[x]-cost2[r+1]-sigma_weigh2[r+1]*((sigma_dis2[x]-sigma_dis2[r+1]+mod)%mod)%mod)%=mod;ans+=mod;ans%=mod;
        }
        if (x<l){
            (ans=cost2[x]-cost2[r+1]-sigma_weigh2[r+1]*((sigma_dis2[x]-sigma_dis2[r+1]+mod)%mod)%mod)%=mod;ans+=mod;ans%=mod;
            (ans-=cost2[x]-cost2[l]-sigma_weigh2[l]*((sigma_dis2[x]-sigma_dis2[l]+mod)%mod)%mod)%=mod;ans+=mod;ans%=mod;
        }
        if (x>r){
            (ans=cost1[x]-cost1[l-1]-sigma_weigh1[l-1]*((sigma_dis1[x]-sigma_dis1[l-1]+mod)%mod)%mod)%=mod;ans+=mod;ans%=mod;
            (ans-=cost1[x]-cost1[r]-sigma_weigh1[r]*((sigma_dis1[x]-sigma_dis1[r])%mod)%mod)%=mod;ans+=mod;ans%=mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页