51nod1712 区间求和
http://www.51nod.com/Challenge/Problem.html#problemId=1712
先考虑题面中的简化问题。
对于\(i\in [1,n]\),\(a_i\)的贡献为\(a_i*(i-1)-a_i*(n-i)\)
那么对于\(i\in [l,r](a_l=a_r)\),贡献为\(a_i*(i-l)-a_i*(r-i)=2i*a_i-a_i(l+r)\)
这个式子只需要统计4个东西就可以\(O(n)\)计算了。
- \(i\)左侧\(a_l\)的个数\(A\)
- \(i\)右侧\(a_r\)的个数\(B\)
- \(i\)左侧\(a_l\)的\(l\)之和\(C\)
- \(i\)右侧\(a_r\)的\(r\)之和\(D\)
那么对答案的贡献就是\(2*i*a_i*A*B-a_i*(BC+AD)\)
统计一下\(A,B,C,D\)即可。
#include <bits/stdc++.h>
using namespace std;
inline int read() {
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x * f;
}
typedef unsigned int uint;
const int N = 1000010;
int n, lim, a[N];
uint num[N], sum[N], numl[N], numr[N], suml[N], sumr[N];
uint Sum, Num;
int main() {
n = read();
for(int i = 1; i <= n; ++i) {
a[i] = read();
numr[a[i]]++; sumr[a[i]] += i;
}
uint ans = 0;
for(int i = 1; i <= n; ++i) {
numl[a[i]]++; suml[a[i]] += i;
Num -= num[a[i]];
num[a[i]] = numl[a[i]] * numr[a[i]];
Num += num[a[i]];
Sum -= sum[a[i]];
sum[a[i]] = suml[a[i]] * numr[a[i]] + sumr[a[i]] * numl[a[i]];
Sum += sum[a[i]];
ans += 2 * i * a[i] * Num - a[i] * Sum;
numr[a[i]]--; sumr[a[i]] -= i;
Num -= num[a[i]];
num[a[i]] = numl[a[i]] * numr[a[i]];
Num += num[a[i]];
Sum -= sum[a[i]];
sum[a[i]] = suml[a[i]] * numr[a[i]] + sumr[a[i]] * numl[a[i]];
Sum += sum[a[i]];
}
printf("%u\n", ans);
}
51nod1712 区间求和的更多相关文章
- POJ 2823 Sliding Window 线段树区间求和问题
题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...
- POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...
- vijos1740 聪明的质监员 (二分、区间求和)
http://www.rqnoj.cn/problem/657 https://www.vijos.org/p/1740 P1740聪明的质检员 请登录后递交 标签:NOIP提高组2011[显示标签] ...
- LightOJ 1112 Curious Robin Hood (单点更新+区间求和)
http://lightoj.com/volume_showproblem.php?problem=1112 题目大意: 1 i 将第i个数值输出,并将第i个值清0 2 i v ...
- POJ 3468 A Simple Problem with Integers(线段树区间求和)
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
转载请注明出处:http://blog.csdn.net/u012860063 Description You have N integers, A1, A2, ... , AN. You need ...
- poj3468树状数组的区间更新,区间求和
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 47174 ...
- D 区间求和 [数学 树状数组]
D 区间求和 题意:求 \[ \sum_{k=1}^n \sum_{l=1}^{n-k+1} \sum_{r=l+k-1}^n 区间前k大值和 \] 比赛时因为被B卡了没有深入想这道题 结果B没做出来 ...
- [用CDQ分治解决区间加&区间求和]【习作】
[前言] 作为一个什么数据结构都不会只会CDQ分治和分块的蒟蒻,面对区间加&区间求和这么难的问题,怎么可能会写线段树呢 于是,用CDQ分治解决区间加&区间求和这篇习作应运而生 [Par ...
随机推荐
- spring boot使用WebClient调用其他系统提供的HTTP服务
WebClient的请求模式属于异步非阻塞,能够以少量固定的线程处理高并发的HTTP请求 WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端 ...
- Docker Compose 部署Nginx服务实现负载均衡
Compose简介: Compose是Docker容器进行编排的工具,定义和运行多容器的应用,可以一条命令启动多个容器,使用Docker Compose,不再需要使用shell脚本来启动容器.Comp ...
- asp.net core使用水晶报表问题
背景 最近项目上遇到一个需求,要后台通过定时任务把水晶报表生成pdf文件,然后邮件发送给相关人. 技术实现思路 选用ASP.NET Core框架(基于2.2版本),通过IHostedS ...
- 配置git diff和git merge使用的第三方工具
一般在运行git merge branchName后,git 如果提示了merger冲突,然后运行git mergetool.Git提示冲突后,运行git mergetool --tool-help ...
- spring data jpa碰到的坑
1.不能从别的类的repository那里 执行另一个类的sql,这样映射会失败. 2.有entity,就要有repository,并且还要有id注解 3.还要多表联查未测试,估计要用map去映射出来 ...
- C/C++ 每日一题
超长正整数的相加,题目链接:https://www.nowcoder.com/practice/5821836e0ec140c1aa29510fd05f45fc?tpId #include<al ...
- python算法介绍:希尔排序
python作为一种新的语言,在很多功能自然要比Java要好一些,也容易让人接受,而且不管您是成年人还是少儿都可以学习这个语言,今天就为大家来分享一个python算法教程之希尔排序,现在我们就来看看吧 ...
- Django框架(十二)-- 中间件、CSRF跨站请求伪造
中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...
- LeetCode二叉树Java模板
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } impor ...
- 【题解】Luogu P5288 [HNOI2019]多边形
原题传送门 HN的题目就是毒瘤 我们有以下猜想: 1.最后所有的线都连到了n号点上 2.最小步数应该为n-3-已经连到n号点的线段数量 本来有些边\((a_i,n)\)会将整个图分割成很多个区间.对于 ...