P3932 浮游大陆的68号岛

P3932 浮游大陆的68号岛

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

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

比如储物点 i 有 x 个东西,要运到储物点 j ,代价为

\[x \times \mathrm{dist}( i , j )\]
dist就是仓库间的距离。

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



错误日志: 题目取模太毒瘤了(其实是因为-1s)


Solution

线段树可做
每个线段树节点维护区间总大小, 区间左右端点, 把物品搬到左端点 / 右端点的代价
那么合并就很显然了, 把东西先挪到子端点再模拟一下搬过去(跨越区间)即可
关于询问
若是点 \(x\) 在区间外, 分情况讨论在左边和在右边, 搞清楚坐标谁减谁即可
若是点 \(x\) 在区间内, 在 \(x\) 处断开, 就相当于两个上一个情况了

第一次用 \(dalao\) 代码风哦
也是第一次见到如此毒瘤的取模题
引用题解的一句话, 把你能想到的所有运算取模

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
#define LL long long
#define REP(i, x, y) for(LL i = (x);i <= (y);i++)
using namespace std;
LL RD(){
    LL out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const LL maxn = 400019, M = 19260817;
LL num, na;
LL p[maxn], v[maxn];
#define lid (id << 1)
#define rid (id << 1) | 1
struct seg_tree{
    LL l, r;
    LL p[2];//左右端点位置
    LL sum;
    LL move[2];//移动到左右花费
    }tree[maxn << 2];
void pushup(LL id){
    tree[id].sum = ((tree[lid].sum + tree[rid].sum) % M + M) % M;
    tree[id].p[0] = tree[lid].p[0];
    tree[id].p[1] = tree[rid].p[1];
    tree[id].move[0] = ((tree[lid].move[0] + tree[rid].move[0]) % M + M) % M + ((tree[rid].sum * (((tree[rid].p[0] - tree[lid].p[0]) % M + M) % M)) % M + M) % M;
    tree[id].move[0] = (tree[id].move[0] % M + M) % M;
    tree[id].move[1] = ((tree[rid].move[1] + tree[lid].move[1]) % M + M) % M + ((tree[lid].sum * (((tree[rid].p[1] - tree[lid].p[1]) % M + M) % M)) % M + M) % M;
    tree[id].move[1] = (tree[id].move[1] % M + M) % M;
    }
void build(LL id, LL l, LL r){
    tree[id].l = l, tree[id].r = r;
    if(l == r){
        tree[id].p[0] = tree[id].p[1] = p[l];
        tree[id].sum = v[l];
        tree[id].move[0] = tree[id].move[1] = 0;
        return ;
        }
    LL mid = (l + r) >> 1;
    build(lid, l, mid), build(rid, mid + 1, r);
    pushup(id);
    }
seg_tree query(LL id, LL l, LL r){
    if(tree[id].l == l && tree[id].r == r)return tree[id];
    LL mid = (tree[id].l + tree[id].r) >> 1;
    if(mid < l)return query(rid, l, r);
    else if(mid >= r)return query(lid, l, r);
    else{
        seg_tree ret, L = query(lid, l, mid), R = query(rid, mid + 1, r);
        ret.sum = ((L.sum + R.sum) % M + M) % M;
        ret.p[0] = L.p[0];
        ret.p[1] = R.p[1];
        ret.move[0] = ((L.move[0] + R.move[0]) % M + M) % M + ((R.sum * (((R.p[0] - L.p[0]) % M + M) % M)) % M + M) % M;
        ret.move[0] = (ret.move[0] % M + M) % M;
        ret.move[1] = ((R.move[1] + L.move[1]) % M + M) % M + ((L.sum * (((R.p[1] - L.p[1]) % M + M) % M)) % M + M) % M;
        ret.move[1] = (ret.move[1] % M + M) % M;
        return ret;
        }
    }
void init(){
    num = RD(), na = RD();
    p[1] = 1;
    REP(i, 2, num)p[i] = p[i - 1] + RD();
    REP(i, 1, num)v[i] = RD() % M;
    build(1, 1, num);
    }
void solve(){
    while(na--){
        LL x = RD(), l = RD(), r = RD();
        if(x <= l){
            seg_tree ans = query(1, l, r);
            LL output = ans.move[0] + ((ans.sum * (((ans.p[0] - p[x]) % M + M) % M)) % M + M) % M;
            printf("%lld\n", (output % M + M) % M);
            }
        else if(x >= r){
            seg_tree ans = query(1, l, r);
            LL output = ans.move[1] + ((ans.sum * (((p[x] - ans.p[1]) % M + M) % M)) % M + M) % M;
            printf("%lld\n", (output % M + M) % M);
            }
        else{
            seg_tree ans = query(1, l, x);
            LL output = ans.move[1] + ((ans.sum * (((p[x] - ans.p[1]) % M + M) % M)) % M + M) % M;
            output = (output % M + M) % M;
            ans = query(1, x, r);
                output = ((output + ans.move[0]) % M + M) % M + ((ans.sum * (((ans.p[0] - p[x]) % M + M) % M)) % M + M) % M;
            printf("%lld\n", (output % M + M) % M);
            }
        }
    }
int main(){
    init();
    solve();
    return 0;
    }

原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9873527.html

时间: 2024-08-01 23:33:48

P3932 浮游大陆的68号岛的相关文章

[Luogu3932] 浮游大陆的68号岛

题目背景 大样例下发链接: https://pan.baidu.com/s/1nuVpRS1 密码: sfxg 浮游大陆的68号岛,位于浮游大陆的边境地带.平时很少有人造访. 岛上被浓厚的森林覆盖. 在这座边境地区不起眼的浮游岛上,建立着神秘的”兵器“管理仓库——妖精仓库. 题目描述 妖精仓库里生活着黄金妖精们,她们过着快乐,却随时准备着迎接死亡的生活. 换用更高尚的说法,是随时准备着为这个无药可救的世界献身. 然而孩子们的生活却总是无忧无虑的,幼体的黄金妖精们过着天真烂漫的生活,自然也无暇考虑

【洛谷八连测R7】nzhtl1477-我回来了

[洛谷八连测R7]nzhtl1477-我回来了 题目描述 68号岛有n个商店,有的商店直接有小路连接,小路的长度都为1,格里克告诉了你哪些地方可能有做黄油蛋糕的原料. 但是那个人是个坑货,所以他会告诉你一些商店,然后告诉你距离这些商店距离 <= k的商店中都是可能有原料的. 然后你要把这些可能的商店每个都去一遍,你想知道你要去多少个商店. 由于你是勇者,所以有m次询问 简洁题意: 给你一个图,每次查询的时候给一堆特殊点以及一个数k,求图中有多少点距离至少一个特殊点距离不超过k,边是无向的. 输入

戴尔维修站查询

戴尔中国大陆维修站点查询 戴尔论坛 www.dell.js.cn 1. 维修站支持机型包括: 台式机.笔记本.平板 部分维修站支持台式机.笔记本.平板.Wyse(CCC-四位数 的维修站) 2. 服务时间:周一至周日 9:00 – 18:00(周日仅提供收机服务),节假日休息 3.为节省消费者们在维修站点的排队等候时间,自2015年2月2日起,客户可通过送修预约服务网站(http://www.cisbooking.com) 或拨打800-858-0655进行送修预约,预约时段为周一到周六,9:0

交通部:油船凝析油失火史无前例 尽最大努力处置

地狱火的攻击居然那么高而现在我正是在慢慢的崛起何况有了龙语者这个强悍的隐藏职业我的崛起绝对能够旷古烁今让整个灵恸大陆为我而颤抖大家又是微微一惊很显然这些法师型怪物的防御力实在是太低了地狱战马看向我的目光似乎柔和了一些了 不到半个小时的时间雪月工作室的几个全部都是名字血红就连夏天的名字也非常红了我和凌雪凌月三个人的名字更是红得发黑就连装备上也是一片血红而秦韵则以惩戒干掉了几个菜鸟之后也加入了红名军团 而我则远离了这些玩家的练级区域选择了近冰谷边缘的区域游弋这里的怪物多是一些级的强化冰熊想对我的等级

jQuery进行简单验证的正则表达式

1.验证电话号码或者手机号码 1 2 3 4 5 6 7 8 9 10 /**   * 验证电话号码(手机号码+电话号码)   * @param obj   * @returns {Boolean}   */ function checkPhoneNum(obj){      if (/^((\d{ 3 }-\d{ 8 }|\d{ 4 }-\d{ 7 , 8 })|( 1 [ 3 | 5 | 7 | 8 ][ 0 - 9 ]{ 9 }))$/.test(obj)){          retur

南昌治疗糖尿病的医院有哪些

▃▅▆▇南 昌 宏 昌 医 院▇▆▅▃医院地址:南昌市象山南路68号(与船山路交叉口) 肾衰竭是肾脏功能在受到损害之后逐渐下降的一种表现,如果没有及时控制和治疗的话,肾衰竭很快就会发展成尿毒症.糖尿病的并发症之一就是糖尿病肾病,那么糖尿病会不会引起肾衰竭呢?下面就由南昌宏昌医院的权威糖尿病治疗专家来讲述一下. 糖尿病肾病是糖尿病并发症中最常见的一种,由于患者体内内分泌失调,胰岛素分泌不足,早期可导致糖尿病患者肾脏代谢困难从而形成肾小球肾炎,且由于患者自身代谢紊乱,肾病治疗存在一定困难,最终会随着

无线电

2017年,共享经济持续成为大众关注的焦点,从共享单车.共享雨伞.共享充电宝,到共享电动车.共享汽车.共享床位,甚至连女友都拿来共享了.戴上"共享"高帽的创业项目一茬接一茬地冒出来,正如收割的韭菜,最开始两茬是最嫩的,接下来生长出来的则会让人觉得食之无味又弃之可惜.对于投资人如此,对于用户们来说有何尝不是呢? 让我们盘点下近一年出现过的"共享"明星们,对于它们,死亡还是生存?这是个问题. 据统计,2016年中国的共享经济市场规模接近4万亿元:2017年,共享系宣告进

基础学习day11--多线程一线程的创建,运行,同步和锁

1.1.进程和线程 进程:一个应用程序一般都是一个进程,正在进行的程序 每一个进程最少都有一个线程,都有一个执行顺序,该顺序是一个执行路径或者一个控制单元 线程:进程中一个独立的控制单元,线程控制着进程的执行. windows中的任务管理器,可以查看进程,linux下通过ps命令 线程是进程的最小单位 线程依赖于进程 线程随着进程的创建和创建,随着进程的结束而消亡 如迅雷:可以同时开启多个下载,就是多线程 多个程序同时执行,时CPU在很快的切换,看上去是同时执行,实际上是在CPU在切换执行. 多

详解DHCP服务安装与管理

DHCP服务安装与管理 一.DHCP是什么 名称:DHCP – Dynamic Host Configuration Protocol 动态主机配置协议 功能:DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作, 主要有两个用途: 1. 给内部网络或网络服务供应商自动分配IP地址,主机名,DNS服务器,域名 2. 配和其它服务,实现集成化管理功能.如:无人执守安装服务器 DHCP是一个C/S架构的协议,D