BZOJ 3922 - Karin的弹幕
2024-08-24 13:27:52
Karin的弹幕
Problem's Link
----------------------------------------------------------------------------
Mean:
给定一个长度为n(1≤n≤70000)序列,有m(1≤m≤70000)次操作:
1. 对一段下标是等差数列的子序列求最大值;
2. 单点修改.
analyse:
如果公差很大,那么速度是很快的。所以我们考虑阈值.
Time complexity: O(N)
view code
/**
* -----------------------------------------------------------------
* 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-); const int N=, MXD=, oo=(~0u>>)+;
int a[N], D, sz[MXD+][MXD+], b[N];
struct node *null;
struct node
{
node *c[];
int mx;
node()
{
c[]=c[]=;
mx=oo;
}
void up()
{
mx=max(c[]->mx, c[]->mx);
}
} Po[], *iT=Po, *root[MXD+][MXD+];
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)>>;
x->c[]=build(l, mid);
x->c[]=build(mid+, 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)>>, ret=oo;
if(L<=mid)
{
ret=query(L, R, l, mid, x->c[]);
}
if(mid<R)
{
ret=max(ret, query(L, R, mid+, r, x->c[]));
}
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)>>;
if(p<=mid)
{
update(p, go, l, mid, x->c[]);
}
else
{
update(p, go, mid+, r, x->c[]);
}
x->up();
}
void init(int n)
{
D=min(MXD, n);
for(int d=; d<=D; ++d)
{
for(int i=; i<=d; ++i)
{
int &s=sz[d][i];
for(int j=i; j<=n; j+=d)
{
b[++s]=a[j];
}
root[d][i]=build(, 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-)%d+, pos=(x-)/d+, len=sz[d][begin];
return query(pos, len, , len, root[d][begin]);
}
void update(int x, int y)
{
a[x]+=y;
for(int d=; d<=D; ++d)
{
int begin=(x-)%d+, pos=(x-)/d+, len=sz[d][begin];
update(pos, y, , len, root[d][begin]);
}
}
int main()
{
int n, m;
scanf("%d", &n);
for(int i=; 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 ;
}
最新文章
- java.lang.ClassCastException: org.slf4j.impl.Log4jLoggerFactory cannot be cast to ch.qos.logback.classic.LoggerContext问题原因及解决方法
- mysql 插入/更新数据
- oracle查询单表占用空间的大小
- Unity的安装和破解
- JavaScript 2016年的概况
- WordPress主题制作教程5:循环
- Swift学习资源
- 用bootstrapValidator来验证UEditor
- wpf ProgressBar使用
- 从零开始的JS生活(一)——JS简介、变量及基本结构
- Linux终端类型
- Docker深入浅出系列教程——Docker简介
- Android IPC机制(四)用ContentProvider进行进程间通信
- Java读取properties文件工具类并解决控制台中文乱码
- LNMP 1.x升级到LNMP 1.4教程及注意事项和多PHP版本使用教程
- vue2之对象属性的监听
- _attribute_creature
- 不用MathType, 如何在Mac Word中插入公式
- Java基础——6种常用类讲解
- IDE MAC下的快捷键,自定义代码块。