首页 > 其他分享 >Non-Puzzle: Segment Pair

Non-Puzzle: Segment Pair

时间:2023-08-14 22:35:53浏览次数:40  
标签:Non r1 r2 long add l2 l1 Pair Segment

题意

给n对区间,要求每对区间恰好选一个使得选出来的n个区间有交集,问有多少方案数

1≤n,l1,l2,r1,r2≤5×10^5

思路

枚举结果以i为左端点的区间的数量,对于每个i,以i为左端点的区间的数量=结果包含i的数量-结果同时包含i和i-1的数量.

对于每对区间,如果两个区间没有重叠部分,那么这对线段对区间内的每个点贡献*1,对区间外的每个点贡献*0,就是不管怎么选也选不到外面的点,就直接*0.

如果有重叠,重叠部分对区间内的每个点贡献*2,就是如果选重叠里面的点,都会有2种选择,所以*2.

需要区间修改和单点查询,使用树状数组维护

#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
const long long mxn=5e5;
long long num[mxn+10],f[mxn+10];//树状数组,num为结果包含i的方案数量,f非0时表示不存在包含i的方案,即线段对贡献*0的个数
long long num2[mxn+10],f2[mxn+10];//树状数组,num为结果同时包含i和i-1的方案数量,f非0时表示不存在同时包含i和i-1的方案,即线段对贡献*0的个数
long long mi[mxn+10];//2^i
long long lowbit(long long i)
{
    return i&(-i);
}
void add(long long flag,long long i,long long x)//更新num,f
{
    if(flag==1)
        while(i<=mxn)
        {
            num[i]+=x;
            i+= lowbit(i);
        }
    else if(flag==2)
        while(i<=mxn)
        {
            f[i]+=x;
            i+= lowbit(i);
        }
}
void add2(long long flag,long long i,long long x)//更新num2,f2
{
    if(flag==1)
        while(i<=mxn)
        {
            num2[i]+=x;
            i+= lowbit(i);
        }
    else if(flag==2)
        while(i<=mxn)
        {
            f2[i]+=x;
            i+= lowbit(i);
        }
}
long long getsum(long long flag,long long i)//获取结果包含i的方案数量
{
    long long ans=0;
    if(flag==1)
        while(i)
        {
            ans+=num[i];
            i-= lowbit(i);
        }
    else if(flag==2)
        while(i)
        {
            ans+=f[i];
            i-= lowbit(i);
        }
    return ans;
}
long long getsum2(long long flag,long long i)//获取结果同时包含i和i-1的方案数量
{
    long long ans=0;
    if(flag==1)
        while(i)
        {
            ans+=num2[i];
            i-= lowbit(i);
        }
    else if(flag==2)
        while(i)
        {
            ans+=f2[i];
            i-= lowbit(i);
        }
    return ans;
}
void solve()
{
    long long n;
    cin>>n;
    mi[0]=1;
    for(long long i=1;i<=mxn+6;i++)
    {
        mi[i]=mi[i-1]*2;
        mi[i]%=mod;
    }
    for(long long i=1;i<=n;i++)
    {
        long long l1,r1,l2,r2;
        cin>>l1>>r1>>l2>>r2;
        if(l1>l2)
        {
            swap(l1,l2);
            swap(r1,r2);
        }
        if(l1==l2)//保证左线段在左边
        {
            if(r1>r2)
                swap(r1,r2);
        }
        if(r1>=l2)//有重叠
        {
            add(1,max(l1,l2),1);
            add(1,min(r2,r1)+1,-1);//重叠部分有i的数量+1
            add2(1,max(l1,l2)+1,1);
            add2(1,min(r2,r1)+1,-1);//重叠部分同时有i和i-1的数量+1
        }
        else//无重叠
        {
            add(2,r1+1,1);
            add(2,l2,-1);//中间因为不存在,贡献*0的数量+1
            add2(2,r1+1,1);
            add2(2,l2+1,-1);//中间因为不存在,贡献*0的数量+1
        }
        //两边不存在,贡献*0的数量+1
        add(2,1,1);
        add(2,min(l1,l2),-1);
        add(2,max(r2,r1)+1,1);
        add(2,mxn+1,-1);
        add2(2,1,1);
        add2(2,min(l1,l2)+1,-1);
        add2(2,max(r2,r1)+1,1);
        add2(2,mxn+1,-1);
    }
    long long sum=0;
    for(long long i=1;i<=mxn;i++)//枚举左端点,数量=包含i数量-同时包含i和i-1的数量
    {
        if(getsum(2,i)==0)//如果结果同时包含i的方案存在
        {
            sum+=mi[getsum(1,i)];//加上包含i的方案数量
            sum%=mod;
            if(getsum2(2,i)==0)//如果结果同时包含i和i-1的方案存在
                sum-=mi[getsum2(1,i)];//减去结果同时包含i和i-1的方案数量,相当于最后sum加上以i开头的区间数量
            while(sum<0) sum+=mod;
            sum%=mod;
        }
    }
    cout<<sum<<endl;
}
signed main()
{
    long long _;
    _=1;
//    cin>>_;
    while(_--) solve();
}

 

标签:Non,r1,r2,long,add,l2,l1,Pair,Segment
From: https://www.cnblogs.com/sleepaday/p/17629963.html

相关文章

  • 2023牛客暑期多校训练营9--I Non-Puzzle: Segment Pair
    思路:直接枚举区间左端点,用一个cnt数组表示当前端点l,r或者L,R存在1个还是2个或者0个。用一个sum变量记录有多少段区间覆盖了该端点,如果sum==n那么这个端点就有了贡献。更详细的看代码注释。#include<bits/stdc++.h>usingnamespacestd;#defineIOSios::sync_with_stdio(fa......
  • 2023牛客多校第九场 D Non-Puzzle: Error Permutation
    题意给定一个长度为n的序列,计算有多少个子区间满足子区间第K小的数不在子区间第K位。 找出所有不满足条件的区间。枚举所有的ai和左端点al,找出满足ai是区间[l,r]中第r-l+1小的右端点r,则右端点r一定是一段区间。例如   342165         l i ......
  • 23牛客多校9 I Non-Puzzle: Segment Pair
    也许更好的阅读体验\(\mathcal{Description}\)给\(n\)对区间,要求每对区间恰好选一个使得选出来的\(n\)个区间有交集,问有多少方案数\(1\len,l_i,r_i\le5×10^5\)\(\mathcal{Solution}\)注意到区间的值域也是\(5×10^5\),考虑从值域入手,也就是枚举每个点看有多少种方案使最后......
  • DP vs Non DP
    我们对知识的探究来源于探寻规律,而许多规律性的问题可以分出阶段进行递推解决,这样就形成了DP。DP非常有用,但它并不能取代找规律的过程。即使是多阶段决策问题,发现一些规律可能比直接使用DP更加简单。例子:你有\(n\)个字母A,\(m\)个字母B,你可以将这些字母组成成为一个字......
  • 【Oracle】CBO统计信息是基于dba_segment 还是dba_tables?
    答案是:来自dba_tables验证过程---首先创建t2,查看当前user_segment以及user_tables信息createtablespacedamondba_tbs01;createuserdamondbaidentifiedbydamondba_tbs01DEFAULTTABLESPACEdamondba_tbs01quotaunlimitedondamondba_tbs01;grantdbatod......
  • TZOJ3326--Barn Repair(优先队列,贪心)
    题目简述: 某天刮了一阵大风,把牛棚的门吹飞了,总共有s个牛棚,幸运的是并不是每个牛棚都有牛。现在你可以购买m块木板,商店里有各种型号的木板,木板长度为多少就需要多少金钱。木板用来给牛棚装上门。要求把所有有牛的牛棚都装上门,并且花的金钱最少。给了一正整数C,接下来C行每行一......
  • python 判空 is None 和 if not None 对比
    Thanksforcomments.Ihavetestedtheperformbetweenthese:importtimeitdefusing_is_none(variable):returnvariableisNonedefusing_if_not_none(variable):returnnotvariablevariable=Noneprint("Using'isNone':",......
  • Striving for Simplicity and Performance in Off-Policy DRL: Output Normalization
    发表时间:2020(ICML2020)文章要点:这篇文章基于SAC做简单并且有效的改进来提升效果。作者首先认为SAC里面的entropy是为了解决actionsaturationduetotheboundednatureoftheactionspaces,这个意思就是说动作空间假如约束到[0-1],动作通常会在0和1两个端点处,而加了entropy可......
  • ethereum错误之nonce too low
    根据提供的错误信息error(*github.com/ethereum/go-ethereum/rpc.jsonError)*{Code:-32000,Message:"noncetoolow",Data:interface{}nil},这是一个来自以太坊的JSON-RPC错误。该错误的含义是“noncetoolow”,即“交易序号(nonce)过低”。在以太坊中,每个账户都有一个交......
  • 基于Pair-wise和CrossEncoder训练单塔模型
    本文分享自华为云社区《语义检索系统排序模块:基于ERNIE-Gram的Pair-wise和基于RocketQA的CrossEncoder训练单塔模型》,作者:汀丶。文本匹配任务数据每一个样本通常由两个文本组成(query,title)。类别形式为0或1,0表示query与title不匹配;1表示匹配。基于单塔Point-wise范......