当前位置:网站首页>2021HNCPC-E-差分,思维
2021HNCPC-E-差分,思维
2022-07-25 15:23:00 【塔子哥来了】
题目大意:
求解每一个 f ( i ) f(i) f(i)代表 m a x ( a j , . . . , a i ) − ( j − i + 1 ) ≥ m max(a_j,...,a_i)-(j-i+1) \geq m max(aj,...,ai)−(j−i+1)≥m的 j j j的个数. j ≤ i j \leq i j≤i
n ≤ 1 e 6 n \leq 1e6 n≤1e6
思路:
关键:看到 m a x ( a j , . . . , a i ) max(a_j,...,a_i) max(aj,...,ai),想到枚举 a i a_i ai,考虑它所管辖的范围(单调栈求解).
PS:当有相同的值时,可以规定将区间贡献记在最右边的值上。
那么就转化成 ( j − i + 1 ) ≤ m a x ( a j , . . . , a i ) − m (j-i+1) \leq max(a_j,...,a_i)-m (j−i+1)≤max(aj,...,ai)−m.
然后枚举右半边,分情况讨论来区间加等差序列即可.
代码仓库:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define vll vector<ll>
#define fi first
#define se second
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
int a[maxn] , l[maxn] , r[maxn] , b[maxn];
int n , m;
template <typename T>
void read(T & x){
x = 0;T f = 1;char ch = getchar();while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();}while (isdigit(ch)){
x = x * 10 + (ch ^ 48);ch = getchar();}x *= f;}
template <typename T>
void write(T x){
if(x < 0){
putchar('-');x = -x;}if (x > 9)write(x / 10);putchar(x % 10 + '0');}
void add (int l , int r , int s , int d){
if (l > r) return ;
int t = s + (r - l) * d;
b[l] += s;
b[l+1] += d - s;
b[r+1] -= d + t;
b[r+2] += t;
}
void solve (){
for (int i = 1 ; i <= n ; i++) b[i] = 0;
for (int i = 1 ; i <= n ; i++){
int g = a[i] - m;
if (g <= 0) continue;
int v = i - l[i] + 1;
if (v >= g){
add(i , min(i + g - 1 , r[i]) , g , -1);
}else{
int gap = g - v;
int e1 = min(i + gap , r[i]);
add(i , e1 , v , 0);
add(e1 + 1 , min(r[i] , e1 + v - 1) , v - 1 , -1);
}
}
for (int i = 1 ; i <= n ; i++) b[i] += b[i - 1];
for (int i = 1 ; i <= n ; i++) b[i] += b[i - 1];
}
int main()
{
while (~scanf("%d%d" , &n, &m)){
for (int i = 1 ; i <= n ; i++) read(a[i]);
stack<int> s;
for (int i = 1 ; i <= n ; i++){
while (s.size() && a[s.top()] <= a[i]) s.pop();
if (s.size()) l[i] = s.top() + 1;
else l[i] = 1;
s.push(i);
}
while (s.size()) s.pop();
for (int i = n ; i >= 1 ; i--){
while (s.size() && a[i] > a[s.top()]) s.pop();
if (s.size()) r[i] = s.top() - 1;
else r[i] = n;
s.push(i);
}
solve();
for (int i = 1 ; i <= n ; i++) printf("%d " , b[i]);
printf("\n");
}
return 0;
}
边栏推荐
猜你喜欢

Spark 内存管理机制 新版

Example of password strength verification

Spark提交参数--files的使用

Implementation of asynchronous FIFO

spark分区算子partitionBy、coalesce、repartition

解决DBeaver SQL Client 连接phoenix查询超时

MySQL installation and configuration super detailed tutorial and simple database and table building method

Graph theory and concept

Simulate setinterval timer with setTimeout

p4552-差分
随机推荐
BPSK调制系统MATLAB仿真实现(1)
IOS interview questions
Delayed loading source code analysis:
wait()和sleep()的区别理解
matlab---错误使用 var 数据类型无效。第一个输入参数必须为单精度值或双精度值
Graph theory and concept
本地缓存--Ehcache
Singleton mode 3-- singleton mode
Tasks, micro tasks, queues and scheduling (animation shows each step of the call)
Spark DF adds a column
Image cropper example
Idea eye care settings
Gbdt source code analysis of boosting
C#精挑整理知识要点11 委托和事件(建议收藏)
ML - 图像 - 深度学习和卷积神经网络
My creation anniversary
小波变换--dwt2 与wavedec2
HBCK fix problem
MySQL heap table_ MySQL memory table heap Usage Summary - Ninth Five Year Plan small pang
JVM-参数配置详解