zoukankan      html  css  js  c++  java
  • JZOJ 4298. 【NOIP2015模拟11.2晚】我的天

    题目

    思路

    其实很好想
    (f_i) 表示 (i) 与编号 (f_i)(i-1) 的人已经相识
    (f_i) 初值为 (i)
    那么转移就是 (f_i = min(f_i,l)) 其中 (l leq i leq r)
    然后更新后的 (f_i) 和以前的 (f_i) 差值和即为答案
    我们可以 (O(n^2)) 更新 (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
    " , ans - last);
    		last = ans;
    	}
    }
    
  • 相关阅读:
    [转][Silverlight] aspx页面上传递参数给Silverlight插件的方法
    [C#] 利用cmd远程网内机器,实现文件互传
    [CSS] 对于一个连在一起很长的字符串,在页面上控制换行
    [CSS] 设置input和img在同一行上
    [MySQL] 记MySQL与MS SQL的几点不同
    [JQuery] 利用jquery的ajax调用后台的WebService公共方法和网页的静态方法
    【计算机组成原理】——计算机发展简史
    【计算机组成原理】——计算机的分类
    【JavaScript高级程序设计4th】第1章 什么是JavaScript——总结
    css重置样式表(两种版本)
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/13434539.html
Copyright © 2011-2022 走看看