BZOJ 3922 - Karin的弹幕
2015-10-10 18:17
253 查看
Karin的弹幕
Problem's Link
----------------------------------------------------------------------------[b]Mean:[/b]
给定一个长度为n(1≤n≤70000)序列,有m(1≤m≤70000)次操作:
1. 对一段下标是等差数列的子序列求最大值;
2. 单点修改.
[b]analyse:[/b]
如果公差很大,那么速度是很快的。所以我们考虑阈值.
[b]Time complexity: O(N)[/b]
[b]view code[/b]
/**
* -----------------------------------------------------------------
* Copyright (c) 2016 crazyacking.All rights reserved.
* -----------------------------------------------------------------
* Author: crazyacking
* Date : 2016-02-15-13.19
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long(LL);
typedef unsigned long long(ULL);
const double eps(1e-8);
const int N=70005, MXD=10, oo=(~0u>>1)+1;
int a[N], D, sz[MXD+1][MXD+1], b[N];
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;
}
相关文章推荐
- JUnit4 与 JMock 之双剑合璧
- 短信验证安卓集成mob.com
- Android之菜单总结
- mocha测试
- Viewpager的setOnPageChangeListener方法详解
- spawn-fcgi 源码分析
- C语言:求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字,例如:2+22+222+2222+22222
- CSU1613 Elephants
- iOS---tableview加载图片的时候的优化之lazy(懒加载)模式and异步加载模式
- WinMain与WndProc以及窗口诞生过程总结
- 手势事件传递
- UIViewController没有随着设备一起旋转的原因
- 老项目Xcode5.1编译器错误
- 使用Volley的imageRequest加载图片实例(含listview异步加载图片错位问题)
- codeforces 324# C. Marina and Vasya (贪心)
- [ERROR] Can't find messagefile '/usr/bin/share/mysql/errmsg.sys'
- 设置屏幕旋转 (以下方法按着顺序设置)
- BerkeleyDB库简介
- 构造 - SGU 109 Magic of David Copperfield II
- 高精度 - SGU 112 a^b-b^a