【BZOJ】3922: Karin的弹幕
2015-11-22 17:50
411 查看
题意
给定一个长度为\(n(1 \le n \le 70000)\)序列,\(m(1 \le m \le 70000)\)次操作:1. 对一段下标是等差数列的子序列求最大值;2. 单点修改。分析
如果公差很大,那么速度是很快的。所以我们考虑阈值。题解
设阈值\(k\)表示如果询问的公差小于等于\(k\)则用线段树求,否则暴力。则我们对阈值每一个公差\(i(1 \le i \le k)\)建\(i\)棵线段树。
复杂度\(O(kn + m(\frac{n}{k} + log n))\)
#include <bits/stdc++.h> using namespace std; const int N=70005, MXD=10, oo=(~0u>>1)+1; int a , D, sz[MXD+1][MXD+1], b ; struct node *null; struct node { node *c[2]; int mx; node() { c[0]=c[1]=0; mx=oo; } void up() { mx=max(c[0]->mx, c[1]->mx); } }Po[10000005], *iT=Po, *root[MXD+1][MXD+1]; node *newnode() { return iT++; } node* build(int l, int r) { node *x=newnode(); if(l==r) { x->mx=b[l]; return x; } int mid=(l+r)>>1; x->c[0]=build(l, mid); x->c[1]=build(mid+1, r); x->up(); return x; } int query(int L, int R, int l, int r, node *x) { if(L<=l && r<=R) { return x->mx; } int mid=(l+r)>>1, ret=oo; if(L<=mid) { ret=query(L, R, l, mid, x->c[0]); } if(mid<R) { ret=max(ret, query(L, R, mid+1, r, x->c[1])); } return ret; } void update(int p, int go, int l, int r, node *x) { if(l==r) { x->mx+=go; return; } int mid=(l+r)>>1; if(p<=mid) { update(p, go, l, mid, x->c[0]); } else { update(p, go, mid+1, r, x->c[1]); } x->up(); } void init(int n) { D=min(MXD, n); for(int d=1; d<=D; ++d) { for(int i=1; i<=d; ++i) { int &s=sz[d][i]; for(int j=i; j<=n; j+=d) { b[++s]=a[j]; } root[d][i]=build(1, s); } } } int query(int x, int d, int n) { if(d>D) { int mx=oo; for(int i=x; i<=n; i+=d) { mx=max(mx, a[i]); } return mx; } int begin=(x-1)%d+1, pos=(x-1)/d+1, len=sz[d][begin]; return query(pos, len, 1, len, root[d][begin]); } void update(int x, int y) { a[x]+=y; for(int d=1; d<=D; ++d) { int begin=(x-1)%d+1, pos=(x-1)/d+1, len=sz[d][begin]; update(pos, y, 1, len, root[d][begin]); } } int main() { int n, m; scanf("%d", &n); for(int i=1; i<=n; ++i) { scanf("%d", &a[i]); } init(n); scanf("%d", &m); while(m--) { int op, x, y; scanf("%d%d%d", &op, &x, &y); if(op) { printf("%d\n", query(x, y, n)); } else { update(x, y); } } return 0; }
相关文章推荐
- k路归并算法的分析和实现
- zzulioj 1780: 和尚特烦恼6——炒股
- OpenGL2 CoreImage初探与Model封装
- 家庭作业汇总
- 一个设置访问权限的实例
- OpenJudge_P7216 Minecraft
- 随笔
- Genymotion安装与使用、Android Studio安装Genymotion插件
- CentOS6.4使用sudo提示用户不在sudoers文件中的解决方法
- java内存区域
- 常用drag控件
- PowerShell GUI 之使用visual studio创建GUI (1)
- iOS--错误集锦--the operation couldn't be completed. (FBSOpenApplicationErrorDomain error 3.)
- FT Introduction
- 单机千万并发连接实战(修订版)
- 数据库优化小技巧总结
- PHP Echo的一些知识,感觉挺有用的
- javascript学习第1节
- 家庭作业汇总
- 腾讯微信技术总监周颢:一亿用户增长背后的架构秘密