首页 > 其他分享 >F. Easy Fix

F. Easy Fix

时间:2022-11-09 22:55:56浏览次数:62  
标签:get int Fix min high que low Easy

F. Easy Fix

题目大意

给定一个排序p。定义A[i][1,i-1]中小于p[i]的数,B[i][i+1,n]中小于p[i]的数。

定义整个排列的贡献为\(\sum_{i=1}^{n}min(A[i],B[i])\)。

现在给出m次操作,每次操作,给出x,y交换排列中p[x],p[y],每次操作独立。

问每次操作后整个排列的贡献是多少。

分析

我们首先可以发现,\(A[i] + B[i] = p_i - 1\)。

我们观察后,可以发现,如果对于一个区间(l,r)中的某个位置i

  • 如果,\(a[i]<min(p[l],p[r])||a[i]>max(p[l],p[r])\),那么交换不会有什么影响。
  • 因此,我们只需要讨论一下,区间中落在\([min(p[l],p[r]),max(p[l],p[r])]\)的数变化。

而这个问题,我们是可以利用二维数点来解决的。

我们来讨论第二种情况的细分情况。

我们先假设\(p[x]<p[y]\)

  • \(A[i]==B[i]\),原来的\(min(A[i],B[i])=A[i]\),现在\(min(A[i]-1,B[i]+1)=A[i]-1\),少1
  • \(A[i]==B[i]+1\),原来的\(min(A[i],B[i])=B[i]\),现在\(min(A[i]-1,B[i]+1)=B[i]\),不变
  • \(A[i]+1==B[i]\),原来的\(min(A[i],B[i])=A[i]\),现在\(min(A[i]-1,B[i]+1)=A[i]-1\),少1
  • \(A[i] \leq B[i] + 2\),原来的\(min(A[i],B[i])=A[i]\),现在\(min(A[i]-1,B[i]+1)=A[i]-1\),少1
  • \(A[i] \geq B[i] + 2\),原来的\(min(A[i],B[i])=B[i]\),现在\(min(A[i]-1,B[i]+1)=B[i]+1\),多1

同理,我们可以推出\(p[x]>p[y]\)的结果。

接着我们来讨论一下,对于边界的l,r,对答案的贡献如何计算。

我们可以先将,原来的贡献减去,再重新加上新的贡献。

那新的贡献是什么呢?我们设(l,r)中小于\(p_l,p_r\)的数分别设为\(d_l,d_r\)

我们交换l,r其实就是\(newA[l] = A[l] + d_l,newB[l] = B[l] - d_l\),\(newA[r] = A[r] - d_r,newB[r] = B[r] + d_r\)。

我们维护这些值,总计需要t1,t2,t3,t4,t5,xx,yy七个二维数点。

AC_code

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;

struct tp {
    // add 添加点
    // que 添加矩形 参数为矩形的左下角,右上角,询问的id 
    // get 传入一个数组,答案会放到数组里面
    static const int maxnum = 2e5 + 5;//数据范围
    static const int maxn = 2e5 + 5;//区间和问题的数量
    int tree[maxnum];
    int n = 0, m = 0;
    struct node1
    {
        int x, y;
    }v[maxn];
    struct node2
    {
        int x, y, id, type;
    } q[maxn << 2];
    static bool cmp1(node1 &a, node1 &b) {
        return a.x < b.x;
    }
    static bool cmp2(node2 &a, node2 &b) {
        return a.x < b.x;
    }
    void update(int idx, int x) {
        while(idx<=maxnum)
        {
            tree[idx] += x;
            idx += idx & -idx;
        }
    }
    int query(int n) {
        int ans = 0;
        while(n)
        {
            ans += tree[n];
            n -= n & -n; 
        }
        return ans;
    }
    int cnt = 0;
    void add(int x, int y) {
        v[++n].x = x, v[n].y = y;
    }
    void que(int x1, int y1, int x2, int y2, int i) {
        q[++cnt] = { x2, y2, i, 1 };
        q[++cnt] = { x1 - 1, y2, i, -1 };
        q[++cnt] = { x2, y1 - 1, i, -1 };
        q[++cnt] = { x1 - 1, y1 - 1, i, 1 };
        m++;
    }
    void get(int *ans) {
        sort(v + 1, v + 1 + n, cmp1);
        sort(q + 1, q + 1 + cnt, cmp2);
        int u = 1;
        for (int i = 1; i <= cnt; i++) {
            while (v[u].x <= q[i].x&&u <= n) {
                update(v[u].y, 1);
                u++;
            }
            ans[q[i].id] += q[i].type * (query(q[i].y));
        }
        for (int i = 1; i <= m; i++) ans[i] = max(ans[i], 0);
    }
};

const int N = 2e5 + 10;

tp t1,t2,t3,t4,t5,xx,yy;
int n,p[N],m,A[N],B[N];
int ans1[N],ans2[N],ans3[N],ans4[N],ans5[N];
int ansxx[N],ansyy[N];
int x[N],y[N];
int tr[N],ans[N];
int sum;

int query(int x)
{
    int res = 0;
    while(x)
    {
        res += tr[x];
        x -= x & -x;
    }
    return res;
}

void add(int x)
{
    while(x<=n)
    {
        tr[x] += 1;
        x += x & -x;
    }
}

int main()
{
    ios;cin>>n;
    for(int i=1;i<=n;i++) cin>>p[i];
    for(int i=1;i<=n;i++)
    {
        A[i] = query(p[i]);
        B[i] = p[i] - 1 - A[i];
        add(p[i]);
        sum += min(A[i],B[i]);
        xx.add(i,p[i]),yy.add(i,p[i]);
    }
    for(int i=1;i<=n;i++)
    {
        if(A[i]==B[i]) t1.add(i,p[i]);
        if(A[i] + 1 == B[i]) t2.add(i,p[i]);
        if(A[i]==B[i] + 1) t3.add(i,p[i]);
        if(A[i] + 2 <= B[i]) t4.add(i,p[i]);
        if(B[i] + 2 <= A[i]) t5.add(i,p[i]);
    }
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>x[i]>>y[i];
        if(x[i]>y[i]) swap(x[i],y[i]);
        int L = x[i] + 1,R = y[i] - 1;
        int low = min(p[x[i]],p[y[i]]),high = max(p[x[i]],p[y[i]]);
        t1.que(L,low,R,high,i);
        t2.que(L,low,R,high,i);
        t3.que(L,low,R,high,i);
        t4.que(L,low,R,high,i);
        t5.que(L,low,R,high,i);
        xx.que(x[i],1,y[i],p[x[i]]-1,i);
        yy.que(x[i],1,y[i],p[y[i]]-1,i);
    }
    t1.get(ans1);
    t2.get(ans2);
    t3.get(ans3);
    t4.get(ans4);
    t5.get(ans5);
    xx.get(ansxx);
    yy.get(ansyy);
    for(int i=1;i<=m;i++){
        if(p[x[i]]<p[y[i]]) ans[i] += sum - ans1[i] - ans2[i] - ans4[i] + ans5[i];
        else ans[i] += sum - ans1[i] - ans3[i] + ans4[i] - ans5[i];
        ans[i] -= min(A[x[i]],B[x[i]]),ans[i] -= min(A[y[i]],B[y[i]]);
        ans[i] += min(A[x[i]] + ansxx[i],B[x[i]] - ansxx[i]),ans[i] += min(A[y[i]] - ansyy[i],B[y[i]] + ansyy[i]);
    }
    for(int i=1;i<=m;i++) cout<<ans[i]<<'\n';
    return 0;
}

标签:get,int,Fix,min,high,que,low,Easy
From: https://www.cnblogs.com/aitejiu/p/16875516.html

相关文章

  • [RoarCTF 2019]Easy Calc
    先打开题目发现是一个计算器,先输入1+1,输出2   先判断是否是SQL注入,发现并没有任何变换Ctrl+u查看源代码,发现提示信息,有waf,发现参数是传到calc.php,num值的加密,在......
  • leetcode-693-easy
    BinaryNumberwithAlternatingBitsGivenapositiveinteger,checkwhetherithasalternatingbits:namely,iftwoadjacentbitswillalwayshavedifferentva......
  • leetcode-2089-easy
    FindTargetIndicesAfterSortingArrayYouaregivena0-indexedintegerarraynumsandatargetelementtarget.Atargetindexisanindexisuchthatnums[......
  • leetcode-1556-easy
    ThousandSeparatorGivenanintegern,addadot(".")asthethousandsseparatorandreturnitinstringformat.Example1:Input:n=987Output:"987"Exa......
  • leetcode-1370-easy
    IncreasingDecreasingStringYouaregivenastrings.Reorderthestringusingthefollowingalgorithm:Pickthesmallestcharacterfromsandappendittot......
  • 视频融合平台EasyCVR如何调用数据库导入导出接口?具体操作步骤是什么?
    EasyCVR视频融合平台部署轻快灵活,支持视频汇聚管理,可提供的视频功能包括:视频监控、直播录像、云存储、检索回看、智能告警、平台级联等。  有用户提出需求,想要定时保......
  • 视频融合平台EasyCVR如何调用数据库导入导出接口?
    EasyCVR视频融合平台部署轻快灵活,支持视频汇聚管理,可提供的视频功能包括:视频监控、直播录像、云存储、检索回看、智能告警、平台级联等。有用户提出需求,想要定时保存数据库,......
  • 上云网关EasyNTS遇到IP冲突时,如何正确更改IP地址?
    在此前的文章中,我们分享过很多关于EasyNTS上云网关平台及硬件的技术性内容,感兴趣的用户可以翻阅往期的文章进行了解。EasyNTS具备内网穿透、组网运维、多协议视频流拉转推......
  • 视频融合平台EasyCVR如何快速更改快照文件的raw后缀?
    EasyCVR视频融合云服务支持多协议、多类型的设备接入,平台可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、级联等功能。在录像功能上,EasyCVR可支持云端录......
  • 国标视频云平台EasyGBS如何批量开启按需直播?
    国标视频云服务EasyGBS支持设备/平台通过国标GB28181协议注册接入,并能实现视频的实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。平台部署简单......