您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: