清北学堂模拟赛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 ...
随机推荐
- 【POJ 3190】 Stall Reservations
[题目链接] http://poj.org/problem?id=3190 [算法] 将这些牛按开始吃草的时间排序 维护一个数组S,Si表示畜栏i进去的最后一头牛结束吃草的时间,对于每头牛,找任意一个 ...
- js和php中几种生成验证码的方式
之前做过取随机数和生成验证码的练习,都是通过取随机数作为数组下标,然后从数组中取值的方式(js): /*验证码*/ function sj_yzm(){ //存一个包括数字和字母的数组 var zon ...
- php字符串读取函数
function cc_msubstr($str, $length, $start=0, $charset="utf-8", $suffix=true){ if(function_ ...
- AcWing算法基础1.3
二分 二分分为整数二分和实数二分,其中整数二分模板有两个 模板: 整数二分模板 第一种模板将区间分为[ l , mid ] 和 [ mid + 1, r ] int bsearch_1(int l, ...
- Codeforces 19E 树上差分
思路: 先随便建出来一棵搜索树(图可能不连通?) 每一条非树边(剩下的边)和树边都可以构成一个环. 我们只看一个非树边和某些树边构成的这些环. 分成三种情况: 1.没有奇环 所有边都可以删 2.有一 ...
- zoj3675 BFS+状态压缩
#include <stdio.h> #include <string.h> #include <queue> using namespace std; int n ...
- jsp动态网页开发基础
JSP基础语法 jsp页面元素构成 jsp页面组成部分有:指令,注释,静态内容,表达式,小脚本,声明. 1.表达式<%= %> 2.小脚本<% %> 3.声 ...
- 对“空引用”说bye-bye
大家可能经常遇到这种情况:当一个对象为null时,调用这个对象的方法或者属性时,就会报错:“Object reference not set to an instance of an object.” ...
- 【转】Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)
概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Ja ...
- 【转】Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理、解决办法)
概要 前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内容包括::1 fail-fast简介2 fail-fast示例 ...