https://www.luogu.org/problemnew/show/P2781

简化版题意:有 n 个数,初始值为 0,进行 m 次操作,每次操作支持将 [l, r] 加 v 和查询 [l, r] 中所有的数的和

n <= 1e9,m <= 1e3

博主 zz 的打了一个支持分裂节点的 splay,AC 后发现可以 m 方暴力过

方法和方伯伯的OJ这题类似,可以参考它的做法

#include <bits/stdc++.h>
using namespace std; typedef unsigned long long ull;
typedef long long ll; template <typename T>
inline void read(T &f) {
f = 0; T fu = 1; char c = getchar();
while(c < '0' || c > '9') {if(c == '-') fu = -1; c = getchar();}
while(c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();}
f *= fu;
} struct Node {
ll val, tag, sum;
int l, r, size;
Node *ch[2];
Node () {
val = tag = l = r = size = 0;
ch[0] = ch[1] = NULL;
}
}*root; int n, m; void update(Node *u) {
u -> size = u -> r - u -> l + 1;
u -> val = u -> sum;
if(u -> ch[0]) u -> size += u -> ch[0] -> size, u -> val += u -> ch[0] -> val;
if(u -> ch[1]) u -> size += u -> ch[1] -> size, u -> val += u -> ch[1] -> val;
} void pushdown(Node *u) {
if(u -> tag) {
if(u -> ch[0]) {
u -> ch[0] -> tag += u -> tag;
u -> ch[0] -> sum += (ll)(u -> ch[0] -> r - u -> ch[0] -> l + 1) * u -> tag;
u -> ch[0] -> val += (ll)u -> ch[0] -> size * u -> tag;
}
if(u -> ch[1]) {
u -> ch[1] -> tag += u -> tag;
u -> ch[1] -> sum += (ll)(u -> ch[1] -> r - u -> ch[1] -> l + 1) * u -> tag;
u -> ch[1] -> val += (ll)u -> ch[1] -> size * u -> tag;
}
u -> tag = 0;
}
} void rotate(Node *&u, int d) {
Node *tmp = u -> ch[d];
u -> ch[d] = tmp -> ch[d ^ 1];
tmp -> ch[d ^ 1] = u;
update(u); update(tmp);
u = tmp;
} void splay(Node *&u, int k) {
if(u == NULL) return;
pushdown(u);
int ltree = u -> ch[0] ? u -> ch[0] -> size : 0;
if(k > ltree && ltree + (u -> r - u -> l + 1) >= k) return;
int d = k > ltree;
splay(u -> ch[d], d ? k - ltree - (u -> r - u -> l + 1) : k);
rotate(u, d);
} void split(Node *&u, int x) {
splay(u, x); ll sum = u -> sum; int l = u -> l, r = u -> r;
if(u -> l != x) {
Node *tmp = new Node();
tmp -> sum = sum / (ll)(r - l + 1) * (x - l);
tmp -> l = l, tmp -> r = x - 1;
tmp -> ch[0] = u -> ch[0]; update(tmp);
u -> ch[0] = tmp; u -> l = x;
}
if(u -> r != x) {
Node *tmp = new Node();
tmp -> sum = sum / (ll)(r - l + 1) * (ll)(r - x);
tmp -> l = x + 1, tmp -> r = r;
tmp -> ch[1] = u -> ch[1]; update(tmp);
u -> ch[1] = tmp; u -> r = x;
}
u -> sum /= (ll)(r - l + 1); update(u);
} int main() {
cin >> n >> m;
root = new Node();
root -> val = root -> tag = root -> sum = 0;
root -> l = 1, root -> r = n; root -> size = n;
root -> ch[0] = root -> ch[1] = NULL;
for(int i = 1; i <= m; i++) {
// printf("root -> size = %d\n", root -> size);
int t; read(t);
if(t == 1) {
int a, b; ll c;
read(a); read(b); read(c);
if(a == 1 && b == n) {
root -> val += (ll)n * c;
root -> tag += c;
root -> sum += (ll)(root -> r - root -> l + 1) * c;
} else if(a == 1) {
split(root, b + 1);
root -> ch[0] -> val += (ll)root -> ch[0] -> size * c;
root -> ch[0] -> tag += c;
root -> ch[0] -> sum += (ll)(root -> ch[0] -> r - root -> ch[0] -> l + 1) * c;
update(root);
} else if(b == n) {
split(root, a - 1);
root -> ch[1] -> val += (ll)root -> ch[1] -> size * c;
root -> ch[1] -> tag += c;
root -> ch[1] -> sum += (ll)(root -> ch[1] -> r - root -> ch[1] -> l + 1) * c;
update(root);
} else {
split(root, b + 1);
split(root -> ch[0], a - 1);
root -> ch[0] -> ch[1] -> val += (ll)root -> ch[0] -> ch[1] -> size * c;
root -> ch[0] -> ch[1] -> tag += c;
root -> ch[0] -> ch[1] -> sum += (ll)(root -> ch[0] -> ch[1] -> r - root -> ch[0] -> ch[1] -> l + 1) * c;
update(root -> ch[0]); update(root);
}
}
if(t == 2) {
int a, b; read(a); read(b);
if(a == 1 && b == n) {
printf("%lld\n", root -> val);
} else if(a == 1) {
split(root, b + 1);
printf("%lld\n", root -> ch[0] -> val);
} else if(b == n) {
split(root, a - 1);
printf("%lld\n", root -> ch[1] -> val);
} else {
split(root, b + 1);
split(root -> ch[0], a - 1);
printf("%lld\n", root -> ch[0] -> ch[1] -> val);
}
}
}
return 0;
}

luoguP2781 传教的更多相关文章

  1. 洛谷——P2781 传教

    P2781 传教 题目背景 写完暑假作业后,bx2k去找pear玩.pear表示他要去汉中传教,于是bx2k准备跟着去围观. 题目描述 pear把即将接受传教的人排成一行,每个人从左到右的编号为1-n ...

  2. 贞鱼传教&&贞鱼传教(数据加强版)

    http://acm.buaa.edu.cn/problem/1381/ 贞鱼传教[问题描述] 新的一年到来了,贞鱼哥决定到世界各地传授“贞教”,他想让“贞教”在2016年成为世界第四大宗教.说干就干 ...

  3. 题解——洛谷P2781 传教(线段树)

    可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\(  n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...

  4. 【Luogu P2781】 传教

    这题是可以用线段树做的. 虽然$n\leq 10^9$ 可以发现,真正需要用到的节点很少,故动态开点,只有需要用到的时候才新建节点. 这里我在下放标记的时候新建节点,因为每操作/查询一个节点都需要先下 ...

  5. Java DNS查询内部实现

    源码分析 在Java中,DNS相关的操作都是通过通过InetAddress提供的API实现的.比如查询域名对应的IP地址: String dottedQuadIpAddress = InetAddre ...

  6. 能力素质模型咨询工具(Part1)

          之前写过由企业家基本素质想到的文章,里面提及一些能力与素质,以下有内容也可以参考: 领导职位 表6-1 远见卓识的行为表现 级 别 行 为 表 现 A (1)关注行业的前景和环境的变化, ...

  7. NOIP模拟赛20161016R1

    1.传教士(bishop) 问题描述: panzhili王国的疆土恰好是一个矩形,为了管理方便,国王jjs将整个疆土划分成N*M块大小相同的区域.由于jjs希望他的子民也能信教爱教(”打拳”神教),所 ...

  8. 【转载】阎焱:90后创业是扯淡 大量O2O和P2P公司濒临倒闭

    真正创业成功的大部分是年龄在30岁到38岁之间,很多90后基本什么都不懂.从历史来看,在这样的人口大国,集体性行为,无论是政治的还是经济的,基本都是导致灾难性后果. 10月14日消息,赛富基金创始首席 ...

  9. 【noip新手入门向】OpenJudge1.3-14大象喝水

    一.写在前面 我也不知道我为什么要写这个鬼畜的东西←_←才不是为了水blog量什么的(划掉),其实是为了明天给学弟学妹们传教准备. 这道题对完全对c语言没有概念的小萌新们极度友好,可以锻炼小萌新们的代 ...

随机推荐

  1. Ansible之Playbooks的when语句

    在使用ansible做自动化运维的时候,大多数情况下都执行某些任务的时候都需要依赖某个变量的值或者是上一个任务的执行结果.如,根据facts信息中的系统版本相关的信息来确定使用哪种包管理器安装软件.A ...

  2. Linux性能监测:CPU篇

    CPU 也是一种硬件资源,和任何其他硬件设备一样也需要驱动和管理程序才能使用,我们可以把内核的进程调度看作是 CPU 的管理程序,用来管理和分配 CPU 资源,合理安排进程抢占 CPU,并决定哪个进程 ...

  3. js控制使div自动适应居中

    一直都在想怎么样使弹出的DIV能在任何时候都是居中显示的,刚开始的时候是用CSS样式直接定义好层的位置,但是当页面很长的时候,或是浏览器窗口大小不是固定的时候就不能正确的显示,所以只好用JS来控制DI ...

  4. MySql主从复制原理和环境配置搭建

    主从复制原理 实质就是通过二进制的sql文件实现主从复制 MySQL的主从复制是MySQL本身自带的一个功能,不需要额外的第三方软件就可以实现,其复制功能并不是copy文件来实现的,而是借助binlo ...

  5. Ubuntu下编写C语言程序

    新建C文件,新建一个文件用touch,新建文件夹用mkdir. 打开文本编辑器,编辑C文件,命令用gedit xxx.C 编写C程序,Ctrl+S保存 编译运行 1.gcc命令是编译 -o是可选项 是 ...

  6. leetcode717

    class Solution { public: bool isOneBitCharacter(vector<int>& bits) { int len = bits.size() ...

  7. Java微信公众平台开发(五)--文本及图文消息回复的实现

    转自:http://www.cuiyongzhi.com/post/43.html 上篇我们说到回复消息可以根据是否需要上传文件到微信服务器可划分为[普通消息]和[多媒体消息],这里我们来讲述普通消息 ...

  8. Tornado之自定义session

      面向对象基础 面向对象中通过索引的方式访问对象,需要内部实现 __getitem__ .__delitem__.__setitem__方法 #!/usr/bin/env python # -*- ...

  9. dokuwiki安装问题

    工作了几年,虽然在程序员这个道路上才算开始,希望以后能够有所成长,为了把平时遇到的技术问题,记录下来,第一个想到的就是写wiki,博客虽然创建了许久,但是没有坚持写下去,在网上找了许多的wiki程序, ...

  10. php扩展开发1--添加函数

    目标:便携php扩展 要求实现 输出hello word 首先用的是php7.0.3   centos7.1或者centos6.+ 1.1 RPM安装PHP rpm -Uvh https://mirr ...