牛客第五场 E.Red and Blue and Green

题意:

要求你构造出一个长度为n的全排列,使它满足给出的m个区间 [ li,ri ] 都满足给出的相应的逆序对个数的奇偶性。

题解:

由于给出的区间要么是重合端点包含关系,要么是不相交包含关系。

我们首先将这个全排列处理为1~n的排列。

然后将m个区间从小到大进行排序然后进行更改。

对于两个不相交的区间,我们如果需要更改区间的奇偶性,直接交换这两个区间的最小值和次小值。

对于重合左端点包含关系,我们将先前遍历的与长区间左端点重合的短区间的最大值x,与x+1进行交换,这样交换之后可以证明正确性。假设对于[1,x]的短区间,使它的x与x+1进行交换,对于与他相邻的[x+1,x+m]短区间,在 [1,x]的短区间中将x变成x+1不改变其逆序对,然后对于[x+1,x+m]短区间把x+1改成x也不改变其逆序对,然后对于包含[1,x]的长区间,他的逆序对个数加1,奇偶性改变。

代码:

#include<bits/stdc++.h>
using namespace std;
int i,j,k,n,m,a[200005],nex[2005],p[20005],change[20005];
struct op
{
    int l,r,t;
} s[2005];
bool cmp(op x,op y)
{
    if (x.r-x.l==y.r-y.l) return x.l<y.l;
    return x.r-x.l<y.r-y.l;
}
int main()
{
    cin>>n>>m;
    for (i=1; i<=n; i++)
    {
        a[i]=i;
        p[i]=i;
        nex[i]=i;
    }
    for (i=1; i<=m; i++)
    {
        cin>>s[i].l>>s[i].r>>s[i].t;
    }
    sort(s+1,s+m+1,cmp);//从短区间到长区间枚举
    for (i=1; i<=m; i++)
    {
        if (s[i].l==s[i].r&&s[i].t==1)
        {
            cout<<-1;
            return 0;
        }
        int cnt=0;
        for (j=s[i].l; j<=s[i].r; j++)
        {
            cnt+=change[j];
        }
        if (s[i].t!=cnt%2)
        {
            swap(a[p[nex[s[i].l]]],a[p[nex[s[i].l]+1]]);
            swap(p[nex[s[i].l]],p[nex[s[i].l]+1]);
            change[s[i].l]++;
        }
        nex[s[i].l]=s[i].r;
    }
    for (i=1; i<=n; i++) cout<<a[i]<<' ';
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值