首页 > 其他分享 >OJ周赛第二场——逆序对

OJ周赛第二场——逆序对

时间:2022-11-07 15:34:36浏览次数:51  
标签:周赛 OJ 10 int 序列 操作 pn 逆序

逆序对  

问题描述 

给你一个长度为n的排列的置换p

(长度为n的排列的置换的定义为:对于排列1,2,3....n,你可以多次交换两个数后的序列。比如(1,5,4,2,3)是一个排列的置换,(3,2,4,2,1)则不是,因为2出现了两次并且5没有出现)

对于序列p{p1,p2,p3,…,pn}有两个操作需要你进行。

1.后置,将序列P的首项放到P的末尾,操作后p′={p2,p3,…,pn,p1}

2.翻转,将序列整个翻转,操作后 p′={pn,pn−1,…,p2,p1}

对于每次操作后,你需要求出操作后序列的逆序对个数。(逆序对的个数为对于序列p,有i<j,pi>pj的个数)

 

输入

第一行给定两个整数n,m (1≤n≤3×10^5,1≤m≤6×10^5) 表示给定序列的长度和操作的次数。

第二行给定n个整数的序列p (1≤pi≤n)。给定的pi保证不会重复。

第三行一个长度为m的字符串。该串有'R'和'S'组成,'R'表示操作2翻转,'S'表示操作1后置 

输出 

输出一行m个数,表示进行第i个操作后的逆序对个数对10取模。具体请看样例。

 

输入例子 1 

5 10
5 4 3 2 1
SSSSRSSSSR

输出例子 1

6446466400

 

提示

原序列的逆序对数为10

第一个操作后为(4,3,2,1,5),逆序对为6,输出6

第二个操作后为(3,2,1,5,4),逆序对为4,输出4

以下同理

 

先求出序列的逆序对,可以通过树状数组或分治求,方法很多。

考虑单独的两个操作

操作1,如果队列第一个为x,那么把他放到最后,我们可以发现,这样原序列后面比他小的数就无法和他形成逆序对,放到后面后会和比他大的数产生逆序对。那么变化为+(x-1)-(n-x)

操作2,原序列为x,那么翻转就是n*(n-1)/2 -x;即全部的减去原来的。

那么如果翻转后再进行操作1,就是相当于把最后一个插到前面,即-(x-1)+(n-x)

 

答案:

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+5;
int f[N];
int n,m;
void add(int x){
    for (;x<=n;x+=x&-x) f[x]++;
}
int sum(int x){
    int s=0;
    for (;x;x-=x&-x) s+=f[x];
    return s;
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    
    
    string s;
    cin>>n>>m;
    
    deque<int> p;
    long long s1=0,all=1LL*n*(n-1)/2;
    for (int i=1;i<=n;++i){
        int x;cin>>x;
        p.push_back(x);
        s1+=sum(n-x);
        add(n-x+1);
    }  // 求p的逆序对
    
    cin>>s;
    
    
    string ans;
    int rev=0;
    for (int i=0;i<m;++i){
        if (s[i]=='S'){
            int x;
            if (rev){
                x=p.back();
                s1=s1 -  (n-x) + (x-1);
                p.pop_back();
                p.push_front(x);
                ans+=char( (all-s1)%10 + '0');
            }else{
                x=p.front();
                s1=s1+ (n-x) - (x-1);
                p.pop_front();
                p.push_back(x);
                ans+=char( s1%10 + '0');
            }
        }else {
            rev^=1;
            if (rev) ans+=char( (all-s1)%10 + '0');
             else     ans+=char( s1%10 + '0');
        }
    }
    
    cout<<ans;
}

 

标签:周赛,OJ,10,int,序列,操作,pn,逆序
From: https://www.cnblogs.com/hihopkc/p/16866118.html

相关文章

  • lc 第318场周赛
    第一次参加我激动的心颤抖的手勉勉强强提交了第一题磕磕绊绊到达并最终倒在了第二题>-<[6229.对数组执行操作]classSolution{public:vector<int>applyO......
  • pat春季模拟考试+acwing第76周赛+AT276
    pat:模考58分,相较夏季赛差了不少1.模拟给定一个字符串,要求按照得分点和失分点进行模拟,求最后得分即可模拟比较难写参考小柳学渣大神的代码,大神码风和思路都很好1#i......
  • LeeCode 318周赛复盘
    T1:对数组执行操作思路:模拟publicint[]applyOperations(int[]nums){intn=nums.length;for(inti=0;i<n-1;++i){if(nums[i]==nums[i+1......
  • 视频播放-videojs
    视频播放-video-js组件安装yarnaddvideo.js--savenpminstallvideo.js--save代码importReact,{useEffect,useRef}from'react';importVideoJsfr......
  • 字符串逆序(多种解法)
    1:>#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>#include<string.h>voidreverse_string(chararr[]){intl=0;intr=strlen(arr)-1;while(l<r){......
  • Acwing76场周赛
    题目链接这次还是只做出来两道题,前两题都挺简单的,注意第二题需要开longlong不开会wa,代码粘上来,以后可能会看吧第一题#include<iostream>#include<string>usingnam......
  • How to create projrect in git
    第一步,在本机选择一个地方,创建一个空目录,如learngit,并进入这个添加的目录:$mkdirlearngit$cdlearngit第二步,通过gitinit命令把这个目录变成Git可以管理的仓库:$git......
  • Project facet Java version 13 is not supported.
    问题导入的文件运行时出现报错:ProjectfacetJavaversion13isnotsupported.大概就是版本不支持,看了下自己的Java版本是1.8的,修改下版本即可运行解决右击文件目录......
  • 6步解决 win7下使用TileStache生成geojson格式的Tiles
      有人说:一个人从1岁活到80岁很平凡,但如果从80岁倒着活,那么一半以上的人都可能不凡。生活没有捷径,我们踩过的坑都成为了生活的经验,这些经验越早知道,你要走的弯路就会越少......
  • [AcWing 788]逆序对的数量
    点击查看代码#include<iostream>usingnamespacestd;constintN=100010;intn;intq[N],tmp[N];typedeflonglongLL;//最坏情况下逆序数为n*(n-1)/2结......