Codeforces 785 E. Anton and Permutation(分块,树状数组)

本文介绍Codeforces785E题目的解题思路,利用分块和Fenwick树来高效处理数组中元素交换后的逆序对数量变化问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Codeforces 785 E. Anton and Permutation
题目大意:给出n,q。n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询。每次查询给出两个数l,r,要求将索引为l,r的两个数交换位置,并给出交换后数组中的逆序对数。
思路:此题用到了分块的思想,即将这组数分为bsz块,在每一块上建Fenwick树,对于每次查询,只需要处理l,r中间的块和l,r所在块受影响的部分。具体实现见代码及注释。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<cmath>
#include<algorithm>
#include<climits> 
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef map<int,int> M;
typedef queue<int> Q;
typedef set<int> S;
typedef vector<int> V;
const int maxn=2e5+10,bsz=2000;
int n; 
int br[maxn],bl[maxn],b[maxn]; //br[i]为编号为i块的右界,bl[i]为编号为i块的左界,b[i]为i点对应的块编号 
struct fenwick
{
    int sum[maxn];
    void add(int p,int x)
    {
        while (p<=n)
        {
            sum[p]+=x;
            p+=p&-p;
        }
    }
    int qry(int p)
    {
        int res=0;
        while (p)
        {
            res+=sum[p];
            p-=p&-p;
        }
        return res;
    }
} fen[maxn/bsz+1];
int a[maxn];
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int i,j,m,q;
    cin>>n>>q;
    //分块、定界
    int bn=(n-1)/bsz+1;
    for (i=0;i<bn;++i)
    {
        bl[i]=i*bsz;
        br[i]=min(n,i*bsz+bsz);
        for (j=bl[i];j<br[i];++j)
            b[j]=i;
    } 
    //数据初始化,上树
    for (i=0;i<n;++i)
    {
        a[i]=i+1;
        fen[b[i]].add(a[i],1);
    }   
    //处理query
    ll ans=0;
    while (q--)
    {
        int l,r;
        cin>>l>>r;
        l--;
        r--;
        if (l==r)
        {
            cout<<ans<<endl;
            continue;
        }
        else if (l>r)
            swap(l,r);
        int less_l=0,less_r=0;
        //处理l,r中间的块
        for (i=b[l]+1;i<b[r];++i)
        {
            less_l+=fen[i].qry(a[l]);
            less_r+=fen[i].qry(a[r]);
        }
        //处理l,r所在块的影响部分 
        if (b[l]!=b[r])
        {
            for (i=l;i<br[b[l]];++i)
            {
                less_l+=a[i]<a[l];
                less_r+=a[i]<a[r];
            }
            for (i=bl[b[r]];i<=r;++i)
            {
                less_l+=a[i]<a[l];
                less_r+=a[i]<a[r]; 
            }
        }
        else
        {
            for (i=l;i<=r;++i)
            {
                less_l+=a[i]<a[l];
                less_r+=a[i]<a[r];
            }
        }
        //由于计算less_l和less_r时,对于端点l,r的处理有重复计数,因此需要修正答案 
        if (a[l]<a[r])
            ans--;
        else
            ans++;
        //更新Fenwick树
         fen[b[l]].add(a[l],-1);
         fen[b[r]].add(a[r],-1);
         swap(a[l],a[r]);
         fen[b[l]].add(a[l],1);
         fen[b[r]].add(a[r],1);
        //处理答案
        int total=r-l;
        ll tmpl=(total-less_l)-less_l;//增加的逆序对数-减少的逆序对数 
        ll tmpr=less_r-(total-less_r); //增加的逆序对数-减少的逆序对数 
        ans+=tmpl+tmpr;
        cout<<ans<<endl; 
    } 
    return 0;
}
 

转载于:https://www.cnblogs.com/orangee/p/9124058.html

内容概要:本文详细介绍了施耐德M580系列PLC的存储结构、系统硬件架构、上电写入程序及CPU冗余特性。在存储结构方面,涵盖拓扑寻址、Device DDT远程寻址以及寄存器寻址三种方式,详细解释了不同类型的寻址方法及其应用场景。系统硬件架构部分,阐述了最小系统的构建要素,包括CPU、机架和模块的选择与配置,并介绍了常见的系统拓扑结构,如简单的机架间拓扑和远程子站以太网菊花链等。上电写入程序环节,说明了通过USB和以太网两种接口进行程序下载的具体步骤,特别是针对初下载时IP地址的设置方法。最后,CPU冗余部分重点描述了热备功能的实现机制,包括IP通讯地址配置和热备拓扑结构。 适合人群:从事工业自动化领域工作的技术人员,特别是对PLC编程及系统集成有一定了解的工程师。 使用场景及目标:①帮助工程师理解施耐德M580系列PLC的寻址机制,以便更好地进行模块配置和编程;②指导工程师完成最小系统的搭建,优化系统拓扑结构的设计;③提供详细的上电写入程序指南,确保程序下载顺利进行;④解释CPU冗余的实现方式,提高系统的稳定性和可靠性。 其他说明:文中还涉及一些特殊模块的功能介绍,如定时器事件和Modbus串口通讯模块,这些内容有助于用户深入了解M580系列PLC的高级应用。此外,附录部分提供了远程子站和热备冗余系统的实物图片,便于用户直观理解相关概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值