test20180919 区间最大值

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了test20180919 区间最大值相关的知识,希望对你有一定的参考价值。

题意

技术分享图片

技术分享图片

分析

我们将所有修改操作的左右端点都拿出来混合着排序。
然后扫描线一样扫描每个端点,维护一个堆储存当前最大值,然后就可以把这些修改操作分成O(m) 个不相交的区间,各自贡献独立。
复杂度为(O(m log m))

浅谈扫描线

把每个区间的l,r+1的左闭右开区间端点混合排序后,其实在扫描左闭右开的区间过程中主要是以下4种情况:

  1. 前一个是l1,这一个是l2,那么其实要加的是[l1,l2-1]这个区间,而l2-1-l1+1=l2-l1
  2. 前一个是l1,这一个是r2+1,那么要加的是[l1,r2]这个区间,而r2-l1+1=r2+1-l1
  3. 前一个是r1+1,这一个是l2,那么要加的是[r1+1,l2-1]这个区间,而l2-1-r1-1+1=l2-r1-1
  4. 前一个是r1+1,这一个是r2+1,那么要加的是[r1+1,r2]这个区间,而r2+1-r1-1=r2-r1-1+1

所以可以直接对区间端点执行减操作,统计答案。
左闭右开区间真好用。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x)
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==‘-‘)
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-‘0‘,ch=getchar();
    return x=data*w;
}
typedef long long ll;
typedef pair<ll,ll> pii;
const int INF=0x7fffffff;

const int MAXN=1e5+7,mod=998244353;

ll maxv[MAXN];

pii A[MAXN<<1];
int sz;

multiset<ll>S;
ll ans;

int pow2(ll x)
{
    x%=mod;
    return (ll)x*x%mod;
}

void addedge(ll x,ll y)
{
    if(S.empty())
        return;
    (ans += (ll)( y-x ) % mod * pow2( *S.rbegin() ) % mod ) %= mod;
}

int main()
{
  freopen("segment.in","r",stdin);
  freopen("segment.out","w",stdout);
    ll n;
    int m;
    read(n);read(m);
    for(int i=1;i<=m;++i)
    {
        ll l,r;
        read(l);read(r);read(maxv[i]);
        A[++sz]=pii(l,i);
        A[++sz]=pii(r+1,-i);
    }
    sort(A+1,A+sz+1);
    for(int i=1;i<=sz;++i)
    {
        if(i > 1 && A[i-1].first < A[i].first)
            addedge(A[i-1].first,A[i].first);
        if(A[i].second > 0)
            S.insert(maxv[A[i].second]);
        else
            S.erase(maxv[-A[i].second]);        
    }
    printf("%lld",ans);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}



以上是关于test20180919 区间最大值的主要内容,如果未能解决你的问题,请参考以下文章

zbb20180919 db 数据库的水平分割和垂直分割

片段(Java) | 机试题+算法思路+考点+代码解析 2023

2021-12-24:划分字母区间。 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 力扣763。某大厂面试

[React Testing] Use Generated Data in Tests with tests-data-bot to Improve Test Maintainability(代码片段

Java 求解划分字母区间

763. 划分字母区间