hdu 4988 Little Pony and Boast Busters ( 树状数组+treap )
题意:
给定n的两个排列, !@#¥%……&**(())*(&)+)*(&…………
http://acm.hdu.edu.cn/showproblem.php?pid=4988
思路:
先把所有数+1.....
两个排列假设是a和b,
先把a数组置换成1,2,3...n, 就是把a[i]换成i, 然后把b数组中等于a[i]的那个b[j]换成i, 然后如果只有一个询问的话就是求出b数组的逆序数。
每种交换都更新下逆序数就行了
对于第二种交换, 就是把b[i]和b[j]交换一下就行, 然后区间加加减减就可以了
对于第一种交换, 就是交换b数组里面的i和j
开一个数组记录一下on[i], 表示数i在b数组里面的下标,然后i=on[i], j=on[j], 就变成第一种交换了。
昨晚刚看了大白的uva11990 , 照着它的思路敲了下uva11990, 但是uva卡到爆, 没交上, 今天BC就来了个类似的,没搞出来可惜了。
虽然昨天刚敲了, 但是今天却完全想不到那个思路, 还很sb地用主席树维护, 智商捉急啊
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <cstdlib>using namespace std;#define inf 0x3f3f3f3f
#define LL long long
#define mxn 100020
#define ls ( p[i].ch[0] )
#define rs ( p[i].ch[1] )struct node {int ch[2];int r, v, s;node() {}node( int v ): v( v ) {ch[0] = ch[1] = 0;r = rand();s = 1;}
}p[mxn*80];
int sz;
int creat( int v ) {++ sz;p[sz] = node( v );return sz;
}
int cmp( int i, int v ) {if( p[i].v == v )return -1;return v < p[i].v ? 0: 1;
}
void mt( int i ) {p[i].s = 1;if( ls )p[i].s += p[ls].s;if( rs )p[i].s += p[rs].s;
}
void rt( int &i, int d ) {int k = p[i].ch[d^1];p[i].ch[d^1] = p[k].ch[d];p[k].ch[d] = i;mt( i ), mt( k );i = k;
}
void insert( int &i, int v ) {if( !i ) {i = creat( v );return ;}int d = cmp( i, v );insert( p[i].ch[d], v );if( p[p[i].ch[d]].r > p[i].r )rt( i, d ^ 1 );mt( i );
}
void Remove( int &i, int v ) {int d = cmp( i, v );if( !~d ) {if( !ls )i = rs;else if( !rs )i = ls;else {int d2 = p[ls].r > p[rs].r ? 1: 0;rt( i, d2 );Remove( p[i].ch[d2], v );}}elseRemove( p[i].ch[d], v );if( i )mt( i );
}
// 小于v的数的个数
int Low( int i, int v ) {if( !i )return 0;int d = cmp( i, v );int ret = 0;if( ls )ret += p[ls].s;if( !~d ) {return ret + 1;}if( d == 0 )return Low( ls, v );return ret + 1 + Low( rs, v );
}
// 大于v的数的个数
int Up( int i, int v ) {if( !i )return 0;int d = cmp( i, v );int ret = 0;if( rs )ret += p[rs].s;if( !~d )return ret + 1;if( d == 1 )return Up( rs, v );return ret + 1 + Up( ls, v );
}
int a[mxn], b[mxn], on[mxn];
int r[mxn], n;
int root[mxn];
int lb( int x ) {return x & -x;
}
void read() {for( int i = 1; i <= n; ++i ) {scanf( "%d", &a[i] );++ a[i];}for( int i = 1; i <= n; ++i ) {scanf( "%d", &b[i] );++ b[i];}for( int i = 1; i <= n; ++i )r[a[i]] = i;for( int i = 1; i <= n; ++i ) {b[i] = r[b[i]]; // 置换b数组on[b[i]] = i; // on[i] 表示 数i的下标}
}
// 更新。。
void update( int x, int v, int d ) {while( x <= n ) {if( d == -1 )Remove( root[x], v );elseinsert( root[x], v );x += lb( x );}
}
int low( int x, int v ) {int ret = 0;while( x ) {ret += Low( root[x], v );x -= lb( x );}return ret;
}
int up( int x, int v ) {int ret = 0;while( x ) {ret += Up( root[x], v );x -= lb( x );}return ret;
}
int main() {while( scanf( "%d", &n ) != EOF ) {sz = 0;read();LL ans = 0;memset( root, 0, sizeof( root ) );// treap + 树状数组for( int i = 1; i <= n; ++i ) {for( int j = i - lb( i ) + 1; j <= i; ++j )insert( root[i], b[j] );}for( int i = 2; i <= n; ++i )ans += up( i - 1, b[i] );int m;scanf( "%d", &m );while( m-- ) {char s[10];scanf( "%s", s );if( s[0] == 'Q' ) {printf( "%I64d\n", ans );continue;}int p, x, y;scanf( "%d%d%d", &p, &x, &y );x ++, y++;if( x == y )continue;if( p == 0 ) {x = on[x], y = on[y];}if( x > y )swap( x, y );if( y - x > 1 ) {ans -= low( y - 1, b[x] ) - low( x, b[x] );ans += up( y - 1, b[x] ) - up( x, b[x] );ans -= up( y - 1, b[y] ) - up( x, b[y] );ans += low( y - 1, b[y] ) - low( x, b[y] );}if( b[x] < b[y] )ans ++;elseans --;update( x, b[x], -1 );update( y, b[y], -1 );update( x, b[y], 1 );update( y, b[x], 1 );swap( on[b[x]], on[b[y]] ); // 要先更新on数组swap( b[x], b[y] );}}return 0;
}
hdu 4988 Little Pony and Boast Busters ( 树状数组+treap )相关推荐
- HDU - 5542 The Battle of Chibi(树状数组+DP)
UVA - 12983 The Battle of Chibi(树状数组+DP) HDU - 5542 The Battle of Chibi(树状数组+DP) #include<cstdio& ...
- hdu 6200 mustedge mustedge mustedge(dfs序+树状数组+并查集)
题目链接:hdu 6200 mustedge mustedge mustedge 题意: 一开始给你一个有n个节点m条无向边的图,现在定义mustedge为u->v的路径上必须经过的边. 现在有 ...
- HDU - 5517 Triple(三维偏序-二维树状数组/CDQ分治)
题目链接:点击查看 题目大意:给出 n 个二元对 ( a , b ) 和 m 个三元对 ( c , d , e ),对于所有 b == e 的二元对和三元对,可以通过某种运算形成一个新的三元对 ( a ...
- HDU 4267 A Simple Problem with Integers [树状数组]
根据%k=a中a和k的不同组合建立55棵树状数组,每次修改操作只对其中1棵树状数组进行操作,每次查询对其中10棵树状数组统计增量和. 1 #include <string.h> 2 #in ...
- HDU 4417 Super Mario(莫队 + 树状数组 + 离散化)
Super Mario 思路 区间查找问题,容易想到离线莫队,确实这题就是莫队,接下来我们考虑如何维护区间高度值问题. 既然是离线嘛,我们容易想到离散化和他挂钩,想想这题是否需要离散化,高度的最大值是 ...
- HDU - 5877 Weak Pair (dfs序+树状数组+离散化)
VJ地址 题意:给一个有根树给你,计算一下满足下列条件的序列对的数目 (1)u是v的祖先(不能是它自己) (2)a[v]*a[u]<=k 思路:用DFS序分裂每一条链,使链上的点都是当前加入点的 ...
- HDU 6447 YJJ's Salesman (dp+树状数组+莫干山算法)
题意:一个 1e9*1e9的方格,从(0,0)走到(1e9,1e9),有个方格有价值,特殊的经过方格可获得价值,每次只能向右.下.右下走,只有右下走到方格的才能获得价值,问最大获得的价值是多少 官方题 ...
- HDU 4358 树状数组+思路
http://acm.hdu.edu.cn/showproblem.php?pid=4358 如图所示,当k==3时,如果我们扫描到红线所在的位置. 则符合条件的区间就是从红线到两条紫线所包含的区间( ...
- hdu 4605 Magic Ball Game (在线主席树/离线树状数组)
版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...
最新文章
- php mysql sql mode_Mysql之SQL Mode用法详解_MySQL
- python爬虫(四)_urllib2:handle处理器和自定义opener
- Tomcat 最新版安装与使用手册,tomcat更改端口号方法,tomcat控制台乱码问题解决方法
- TestNG方法測试及注意要点 代码及配置具体解释(解决testng方法不运行问题)
- UC伯克利摘最佳论文、Hugging Face获最佳demo,EMNLP 2020奖项公布
- Spark任务提交后是如何完成提交过程的?源码解析!
- POE交换机产品如何设计防雷保护?
- codeigniter_如何在浏览器中查看CodeIgniter日志文件
- C中关于存储类的理解
- 红橙Darren视频笔记 界面优化与屏幕适配(上)
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛——F题 成绩查询ing
- java 覆盖文件_java复制文件(如果目标文件存在,是否覆盖)
- plsqldev显示语言有问题
- DreamWeaver CC网页设计与制作
- PowerShell,AnkhSVN和Subversion
- 解决TypeError: conv2d() received an invalid combination of arguments
- 阿里巴巴矢量图标引用问题
- 切比雪夫插值多项式在非线性电路中的应用与比较
- cuda性能分析工具
- 深入学习ArduinoJson库 V5版本
热门文章
- 乌合之众-大众心理研究(十四)
- 频率响应、零极点和系统稳定性
- 二套模板的小说网站源码 带采集功能
- keil5“魔法棒”配置
- 单变量微积分笔记——积分的应用
- easyExcel自定义格式转换
- 给你安利几款好用的音频转换ogg格式的软件
- 关于使用工具包,应用程序中发生了无法处理的异常。如果单击“继续”,应用程序忽略错误尝试继续运行。点击退出,应用程序将会“关闭”。异常来自HRESULT:0x80040228的错误问题!
- linux迷宫游戏,宝藏迷宫逃离
- zset获取指定score_redis zset更新score redis学习笔记5 - Redis - 服务器之家