清北学堂模拟赛d2t3 逆序对(pair)
题目描述
LYK最近在研究逆序对。
这个问题是这样的。
一开始LYK有一个2^n长度的数组ai。
LYK有Q次操作,每次操作都有一个参数k。表示每连续2^k长度作为一个小组。假设n=4,k=2,则a[1],a[2],a[3],a[4]为一个小组,a[5],a[6],a[7],a[8]为一个小组,a[9],a[10],a[11],a[12]为一个小组,a[13],a[14],a[15],a[16]也为一个小组。
然后LYK对于每个小组都翻转,也就是说原数组会变成a[4],a[3],a[2],a[1],a[8],a[7],a[6],a[5],a[12],a[11],a[10],a[9],a[16],a[15],a[14],a[13]。之后它想求出这2^n个数的逆序对是多少。
因此你需要输出对于每次操作,操作完后这2^n个数的逆序对有多少对。
两个数ai,aj被称为逆序对当且仅当i<j且ai>aj。
输入格式(pair.in)
第一行一个数n。
接下来一行2^n个数ai表示一开始的数组。
接下来一行一个数Q,表示操作的次数。
接下来一行Q个数,表示每次操作的参数k。
输出格式(pair.out)
Q行,表示每次操作后的答案。
输入样例
2
2 1 4 3
4
1 2 0 2
输出样例
0
6
6
0
样例解释
第一次操作,{2,1,4,3}->{1,2,3,4}
第二次操作,{1,2,3,4}->{4,3,2,1}
第三次操作,{4,3,2,1}->{4,3,2,1}
第四次操作,{4,3,2,1}->{1,2,3,4}
对于30%的数据n<=10,Q<=10。
对于50%的数据n<=10,Q<=1000。
对于80%的数据n<=10,Q<=200000。
对于100%的数据n<=17,Q<=200000,1<=ai<=2^n。
分析:比较巧妙的一道题。每次翻转操作其实就是将一个区间的逆序对个数与顺序对个数交换,那么先用归并排序求出逆序对的同时求出顺序对。接下来可以把翻转操作进行分解:假设交换翻转1234
1,2,3,4 ---> 1,2 3,4 ---> 3,4 1,2 --->4,3,2,1.对每一个子区间的逆序对进行分析,可以知道每个元素的贡献是这个元素在区间长度为1的逆序对数+区间长度为2的逆序对数+区间长度为4的逆序数......
每次修改操作只是更改了长度小于等于2^k的区间的逆序对数,对于长度大于2^k的区间就不用修改了.统计的时候把各个长度的区间答案加起来就是了.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; long long n, a[( << ) + ],q,cnt[( << ) + ][],b[( << ) + ],k;
long long ans; void Sort(int l, int r, int dep)
{
if (l >= r)
return;
int mid = (l + r) >> ;
Sort(l, mid, dep - );
Sort(mid + , r, dep - );
int i = l, j = mid + , res = ;
while (i <= mid && j <= r)
{
if (a[i] < a[j])
{
cnt[dep][] += r - j + ;
i++;
}
else
j++;
}
i = l, j = mid + ;
while (i <= mid && j <= r)
{
if (a[i] > a[j])
{
cnt[dep][] += mid - i + ;
b[++res] = a[j++];
}
else
b[++res] = a[i++];
}
while (i <= mid)
b[++res] = a[i++];
while (j <= r)
b[++res] = a[j++];
for (int i = l; i <= r; i++)
a[i] = b[i - l + ];
} int main()
{
scanf("%lld", &n);
for (int i = ; i <= ( << n); i++)
scanf("%lld", &a[i]);
Sort(, << n, n);
scanf("%lld", &q);
while (q--)
{
scanf("%lld", &k);
ans = ;
for (int i = ; i <= n; i++)
{
if (i <= k)
swap(cnt[i][], cnt[i][]);
ans += cnt[i][];
}
printf("%lld\n", ans);
} return ;
}
清北学堂模拟赛d2t3 逆序对(pair)的更多相关文章
- 清北学堂模拟赛day7 数字碰撞
/* clj:水题别人都满分你不是你就完了,所以说水题一定要细心一点,有这么几个细节:①前导零的处理,全是零的时候要特判②换行要注意,不要多大一行,剩下就是水水的模拟了 */ #include< ...
- 清北学堂模拟赛d4t1 a
分析:大模拟,没什么好说的.我在考场上犯了一个超级低级的错误:while (scanf("%s",s + 1)),导致了死循环,血的教训啊,以后要记住了. /* 1.没有发生改变, ...
- 清北学堂模拟赛day7 错排问题
/* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x ...
- 清北学堂模拟赛day7 石子合并加强版
/* 注意到合并三堆需要枚举两个端点,其实可以开一个数组记录合并两堆的结果,标程好像用了一个神奇的优化 */ #include<iostream> #include<cstdio&g ...
- 清北学堂模拟赛d6t6 棋盘迷宫
3.棋盘迷宫(boardgame.pas/c/cpp)(boardgame.in/out)时间限制:5s/空间限制:256M[题目描述]小 A 和小 Z 是非常要好的朋友, 而且他们都对迷宫游戏非常有 ...
- 清北学堂模拟赛d1t2 火柴棒 (stick)
题目描述众所周知的是,火柴棒可以拼成各种各样的数字.具体可以看下图: 通过2根火柴棒可以拼出数字“1”,通过5根火柴棒可以拼出数字“2”,以此类推. 现在LYK拥有k根火柴棒,它想将这k根火柴棒恰好用 ...
- 清北学堂模拟赛d1t1 位运算1(bit)
题目描述LYK拥有一个十进制的数N.它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N所拥有的价值.例如数字123拥有6的价值,数字999拥有27的价值.假设数字N的价值是K,LYK想找到一个 ...
- 清北学堂模拟赛d2t6 分糖果(candy)
题目描述总共有n颗糖果,有3个小朋友分别叫做L,Y,K.每个小朋友想拿到至少k颗糖果,但这三个小朋友有一个共同的特点:对3反感.也就是说,如果某个小朋友拿到3颗,13颗,31颗,333颗这样数量的糖果 ...
- 清北学堂模拟赛d2t5 吃东西(eat)
题目描述一个神秘的村庄里有4家美食店.这四家店分别有A,B,C,D种不同的美食.LYK想在每一家店都吃其中一种美食.每种美食需要吃的时间可能是不一样的.现在给定第1家店A种不同的美食所需要吃的时间a1 ...
随机推荐
- JSP-Runoob:JSP 点击量统计
ylbtech-JSP-Runoob:JSP 点击量统计 1.返回顶部 1. JSP 点击量统计 有时候我们需要知道某个页面被访问的次数,这时我们就需要在页面上添加页面统计器,页面访问的统计一般在用户 ...
- Linux进程状态查询
进程状态详细说明 Linux进程状态详细解析 ps 的参数说明 ps 提供了很多的选项参数,常用的有以下几个: l 长格式输出: u 按用户名和启动时间的顺序来显示进程: ...
- codevs2503失恋28天......(背包dp)
503 失恋28天-缝补礼物 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 话说上回他给女孩送了n件礼物,由于是廉价的所以 ...
- cglib动态代理(即AOP)
Computer.java package com.wh.spring_aop; public class Computer { public void playLOL(){ System.out.p ...
- 【LeetCode】-- 260. Single Number III
问题描述: https://leetcode.com/problems/single-number-iii/ 在一个数组里面,只有两个元素仅出现过1次,其余都出现过两次.找出出现仅一次的那两个(a, ...
- 315 Count of Smaller Numbers After Self 计算右侧小于当前元素的个数
给定一个整型数组 nums,按要求返回一个新的 counts 数组.数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于nums[i] 的元素的数量.例子:给定 nu ...
- Bootstrap3模态框Modal垂直居中样式
1,Bootstrap 模态框插件Bootbox垂直居中样式: <!DOCTYPE html> <html lang="en"> <head> ...
- 简单TCP代码
服务器: SOCKET s; s = ::socket(AF_INET,SOCK_STREAM,); sockaddr_in addr; addr.sin_family = AF_INET; addr ...
- JS——input标签注册事件
注意:淘宝的lable是用定位制作的,事件是oninput事件 <!DOCTYPE html> <html> <head lang="en"> ...
- MyEclipse中VSS的使用详解
本文系转载,原文地址http://hi.baidu.com/yi88cheng/blog/item/13dd862f765e6b5c4fc226e5.html