\(>Codeforces\space992 E. Nastya and King-Shamans<\)

题目大意 : 给你一个长度为 \(n\) 的序列,有 \(q\) 次操作,每一次操作将一个数 \(A_i\) 改为另外一个数。每一次操作结束时,你需要找出一个位置 \(x\) 满足 \(A_x = sum_{x-1}\) 其中 \(sum\) 表示前缀和

$n , q \leq 2 \times 10^5 \ 0 \leq A_i \leq 10^9 $

解题思路 :

博主亲测分块加均摊分析的做法会因为常数太大 \(TLE\) 掉,在此就不多讨论了

问题要求出满足 \(A_x = sum_{x-1}\) 的位置,这个可以转化为 \(sum_x = 2 \times sum_{x-1}\)

我们考虑从 \(A_{p=1}\) 开始跳,每一次跳到其后面一个最小的 \(k - 1\) ,满足\(sum_k \geq 2 \times sum_p\)

可以证明如果有答案且 \(sum_{ans} > 0\),那么答案一定在所有的 \(k\) 之中产生

不妨用反证法来证明,假设当且跳到点 \(k\) ,接下来选取的点是 \(k' \ (k < k')\) ,对于 \(k < i < k' - 1\)

如果说 \(i\) 是答案的话,设 \(y\) 为 第一个满足 $ sum_y \geq 2 \times sum_i$ 的点。

因为\(sum_y \geq sumk\) 所以必然有 $ y \geq k' $ ,如果 \(i < k' - 1\) 那么 $ y - i > 1$ , \(i\) 不是答案

所以证明了这样跳,如果有答案的话答案必然在跳到的点上

所以可以用树状数组维护前缀和,每一次暴力二分跳,跳 \(log\) 次就能跳完,总复杂度是\(O(nlog^3n)\)

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
if(f) x = -x;
}
#define N (300005)
#define int ll
ll c[N], a[N], n, q;
inline void add(int x, ll y){ for(int i = x; i <= n; i += i & -i) c[i] += y; }
inline ll sum(int x){ ll ans = 0; for(int i = x; i; i -= i & -i) ans += c[i]; return ans; }
inline void solve(){
int x = 1;
if(sum(1) == 0) return (void)( puts("1") );
while(x < n){
int l = x + 1, r = n, k = x, now = 2 * sum(x);
if(sum(x + 1) == now) return (void) (printf("%d\n", x + 1));
while(l <= r){
int mid = l + r >> 1;
if(sum(mid) < now) k = mid, l = mid + 1; else r = mid - 1;
}
if(k + 1 > n) break;
x = (k == x) ? k + 1 : k;
}
puts("-1");
}
main(){
read(n), read(q);
for(int i = 1; i <= n; i++) read(a[i]), add(i, a[i]);
for(int i = 1; i <= q; i++){
int x, y; read(x), read(y);
add(x, y - a[x]), a[x] = y, solve();
}
return 0;
}

最新文章

  1. Android studio快捷键大全 和 eclipse对照(原)
  2. Ue4中的框选函数
  3. Flume连接Kafka的broker出错
  4. CSS2书写顺序
  5. 中文版Chrome浏览器不支持12px以下字体的解决方案
  6. COB(Chip On Board) 工艺技术
  7. EasyUI - Combo组件
  8. Java ArrayList、Vector和LinkedList等的差别与用法(转)
  9. 1131: [POI2008]Sta
  10. 进程间通信系列 之 消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例
  11. 自动化运维工具——ansible详解(二)
  12. eclipse代码编辑区字符串自动转义设置
  13. windows 下 nginx log 分割
  14. AD账号解锁
  15. 基于Elasticsearch 5.4.3的商品搜索系统
  16. 解决windows系统的oracle数据库不能启动ora-00119和ora-00130的问题
  17. CentOS配置163yum源
  18. 关于EF的一点小记录
  19. 【oracle的安装和基本配置】
  20. 05-python中函数的使用

热门文章

  1. Eclipse 断点调试
  2. 20155117王震宇 实验一《Java开发环境的熟悉》实验报告
  3. oozie与hive的简单案例
  4. NYOJ 409 郁闷的C小加(三) (字符串处理)
  5. CAD启动提示&quot;是否关闭命令行&quot;不管点击什么,都会闪退的解决办法
  6. 动态规划_01背包问题_Java实现
  7. 2-Python基础语法-内存管理-运算符-程序控制
  8. MySQL常见错误代码说明
  9. Java 序列化工具类
  10. [ python ] 字符串的操作及作业题