JZOJ 4298. 【NOIP2015模拟11.2晚】我的天

题目

思路

其实很好想
fi 表示 i 与编号 fii1 的人已经相识
fi 初值为 i
那么转移就是 fi=min(fi,l) 其中 lir
然后更新后的 fi 和以前的 fi 差值和即为答案
我们可以 O(n2) 更新 f
可以拿 50

然后可以发现 f 数组具有单调性,适当 break 就行了
可以拿 70

满分做法其实已经能很容易看出
我们对 f 的更新相当于每次对区间取 min
吉司机线段树维护一下就好
维护 f 的和和一些套路的东西
答案其实是这次整体的 f 的和减去上次 f 的整体和
这就是新增

Code

#include<cstdio>
#include<iostream>
#define ls (k << 1)
#define rs (ls | 1)
using namespace std;
typedef long long LL;
const int N = 3e5 + 5;
int n , m , INF = 0x3f3f3f3f;
LL last;
struct segment{
LL sum;
int mx , se , cnt , tag;
}seg[N << 2];
inline void pushup(int k)
{
seg[k].sum = seg[ls].sum + seg[rs].sum;
seg[k].mx = max(seg[ls].mx , seg[rs].mx);
if (seg[ls].mx == seg[rs].mx)
{
seg[k].se = max(seg[ls].se , seg[rs].se);
seg[k].cnt = seg[ls].cnt + seg[rs].cnt;
}
else if (seg[ls].mx < seg[rs].mx)
{
seg[k].se = max(seg[ls].mx , seg[rs].se);
seg[k].cnt = seg[rs].cnt;
}
else {
seg[k].se = max(seg[ls].se , seg[rs].mx);
seg[k].cnt = seg[ls].cnt;
}
}
inline void build(int l , int r , int k)
{
seg[k].tag = INF;
if (l == r)
{
seg[k].mx = l , seg[k].se = -INF , seg[k].cnt = 1;
return;
}
int mid = (l + r) >> 1;
build(l , mid , ls) , build(mid + 1 , r , rs);
pushup(k);
}
inline void push_min(int k , int z)
{
if (z >= seg[k].mx) return;
seg[k].sum += 1LL * (seg[k].mx - z) * seg[k].cnt;
seg[k].mx = seg[k].tag = z;
}
inline void pushdown(int l , int r , int k)
{
int mid = (l + r) >> 1;
if (seg[k].tag)
{
push_min(ls , seg[k].tag) , push_min(rs , seg[k].tag);
seg[k].tag = INF;
}
}
inline void update(int x , int y , int z , int l , int r , int k)
{
if (z >= seg[k].mx) return;
if (x <= l && r <= y && seg[k].se < z) return push_min(k , z);
pushdown(l , r , k);
int mid = (l + r) >> 1;
if (x <= mid) update(x , y , z , l , mid , ls);
if (y > mid) update(x , y , z , mid + 1 , r , rs);
pushup(k);
}
inline LL query(int x , int y , int l , int r , int k)
{
if (x <= l && r <= y) return seg[k].sum;
pushdown(l , r , k);
LL res = 0;
int mid = (l + r) >> 1;
if (x <= mid) res += query(x , y , l , mid , ls);
if (y > mid) res += query(x , y , mid + 1 , r , rs);
return res;
}
int main()
{
freopen("ohmygod.in" , "r" , stdin);
freopen("ohmygod.out" , "w" , stdout);
scanf("%d%d" , &n , &m);
int x , y;
build(1 , n , 1);
while (m--)
{
scanf("%d%d" , &x , &y);
update(x , y , x , 1 , n , 1);
LL ans = query(1 , n , 1 , n , 1);
printf("%lld\n" , ans - last);
last = ans;
}
}
posted @   leiyuanze  阅读(123)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示