luoguP2781 传教
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 传教的更多相关文章
- 洛谷——P2781 传教
		
P2781 传教 题目背景 写完暑假作业后,bx2k去找pear玩.pear表示他要去汉中传教,于是bx2k准备跟着去围观. 题目描述 pear把即将接受传教的人排成一行,每个人从左到右的编号为1-n ...
 - 贞鱼传教&&贞鱼传教(数据加强版)
		
http://acm.buaa.edu.cn/problem/1381/ 贞鱼传教[问题描述] 新的一年到来了,贞鱼哥决定到世界各地传授“贞教”,他想让“贞教”在2016年成为世界第四大宗教.说干就干 ...
 - 题解——洛谷P2781 传教(线段树)
		
可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\( n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...
 - 【Luogu P2781】 传教
		
这题是可以用线段树做的. 虽然$n\leq 10^9$ 可以发现,真正需要用到的节点很少,故动态开点,只有需要用到的时候才新建节点. 这里我在下放标记的时候新建节点,因为每操作/查询一个节点都需要先下 ...
 - Java DNS查询内部实现
		
源码分析 在Java中,DNS相关的操作都是通过通过InetAddress提供的API实现的.比如查询域名对应的IP地址: String dottedQuadIpAddress = InetAddre ...
 - 能力素质模型咨询工具(Part1)
		
之前写过由企业家基本素质想到的文章,里面提及一些能力与素质,以下有内容也可以参考: 领导职位 表6-1 远见卓识的行为表现 级 别 行 为 表 现 A (1)关注行业的前景和环境的变化, ...
 - NOIP模拟赛20161016R1
		
1.传教士(bishop) 问题描述: panzhili王国的疆土恰好是一个矩形,为了管理方便,国王jjs将整个疆土划分成N*M块大小相同的区域.由于jjs希望他的子民也能信教爱教(”打拳”神教),所 ...
 - 【转载】阎焱:90后创业是扯淡 大量O2O和P2P公司濒临倒闭
		
真正创业成功的大部分是年龄在30岁到38岁之间,很多90后基本什么都不懂.从历史来看,在这样的人口大国,集体性行为,无论是政治的还是经济的,基本都是导致灾难性后果. 10月14日消息,赛富基金创始首席 ...
 - 【noip新手入门向】OpenJudge1.3-14大象喝水
		
一.写在前面 我也不知道我为什么要写这个鬼畜的东西←_←才不是为了水blog量什么的(划掉),其实是为了明天给学弟学妹们传教准备. 这道题对完全对c语言没有概念的小萌新们极度友好,可以锻炼小萌新们的代 ...
 
随机推荐
- java - 只输出不含中文标点符号的中文
			
String a ="12dss显示,‘:()中文只"; StringBuffer b = new StringBuffer(); for(int i = 0;i<a.len ...
 - 转:Python正则表达式指南
			
本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例.本文的内容不包括如何编写高效的正则表达式.如何优化正则表达式,这些主题请查看其他教程 ...
 - java的mysql初探
			
在实现如下demo之前,要安装mysql的驱动mysql-connector-java-gpl-5.1.26.msi DEMO: /* * 简单数据库测试 * @李志杰 * 2013-8-4 */ p ...
 - Project2--Lucene的Ranking算法修改:BM25算法
			
原文出自:http://blog.csdn.net/wbia2010lkl/article/details/6046661 1. BM25算法 BM25是二元独立模型的扩展,其得分函数有很 ...
 - noip2010 关押罪犯 (vijos1776)
			
题目 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪 ...
 - mongo_1 新手之路
			
mongodb 进入.在bin目录下 至于安装各位自己查资料吧 .不废话了 直接上图.这种表示已经成功进入mongo 本人mongo 数据库存放地址.如有需要可以清空可以自己删除. 接下来就是 ...
 - SQL SERVER 2008权限配置
			
我要的结果是这样:只能有查询表的权限,而且还要有运行SQL Server Profiler的权限.这样才能跟踪发现问题,当然解决问题是另外一回事,即不能有修改和更新存储过程的权限. 我在分配角色成员时 ...
 - C#实现访问网络共享文件夹
			
C#实现访问网络共享文件夹,使用 WNetAddConnection2A 和 WNetCancelConnection2A. 在目标服务器建立共享文件夹,建立访问账号test; public enum ...
 - PCL 常用小知识
			
时间计算 pcl中计算程序运行时间有很多函数,其中利用控制台的时间计算 首先必须包含头文件 #include <pcl/console/time.h> #include <pcl/c ...
 - WEB前端--CSS
			
一.认识CSS 1.概念 CSS(Cascading Style Sheet,层叠样式表),可以将网页制作的更加绚丽多彩.它可以有效的对页面的布局.字体.颜色.背景和其它效果实现更加精确的控制. 2. ...