题意:

给定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 )相关推荐

  1. HDU - 5542 The Battle of Chibi(树状数组+DP)

    UVA - 12983 The Battle of Chibi(树状数组+DP) HDU - 5542 The Battle of Chibi(树状数组+DP) #include<cstdio& ...

  2. hdu 6200 mustedge mustedge mustedge(dfs序+树状数组+并查集)

    题目链接:hdu 6200 mustedge mustedge mustedge 题意: 一开始给你一个有n个节点m条无向边的图,现在定义mustedge为u->v的路径上必须经过的边. 现在有 ...

  3. HDU - 5517 Triple(三维偏序-二维树状数组/CDQ分治)

    题目链接:点击查看 题目大意:给出 n 个二元对 ( a , b ) 和 m 个三元对 ( c , d , e ),对于所有 b == e 的二元对和三元对,可以通过某种运算形成一个新的三元对 ( a ...

  4. HDU 4267 A Simple Problem with Integers [树状数组]

    根据%k=a中a和k的不同组合建立55棵树状数组,每次修改操作只对其中1棵树状数组进行操作,每次查询对其中10棵树状数组统计增量和. 1 #include <string.h> 2 #in ...

  5. HDU 4417 Super Mario(莫队 + 树状数组 + 离散化)

    Super Mario 思路 区间查找问题,容易想到离线莫队,确实这题就是莫队,接下来我们考虑如何维护区间高度值问题. 既然是离线嘛,我们容易想到离散化和他挂钩,想想这题是否需要离散化,高度的最大值是 ...

  6. HDU - 5877 Weak Pair (dfs序+树状数组+离散化)

    VJ地址 题意:给一个有根树给你,计算一下满足下列条件的序列对的数目 (1)u是v的祖先(不能是它自己) (2)a[v]*a[u]<=k 思路:用DFS序分裂每一条链,使链上的点都是当前加入点的 ...

  7. HDU 6447 YJJ's Salesman (dp+树状数组+莫干山算法)

    题意:一个 1e9*1e9的方格,从(0,0)走到(1e9,1e9),有个方格有价值,特殊的经过方格可获得价值,每次只能向右.下.右下走,只有右下走到方格的才能获得价值,问最大获得的价值是多少 官方题 ...

  8. HDU 4358 树状数组+思路

    http://acm.hdu.edu.cn/showproblem.php?pid=4358 如图所示,当k==3时,如果我们扫描到红线所在的位置. 则符合条件的区间就是从红线到两条紫线所包含的区间( ...

  9. hdu 4605 Magic Ball Game (在线主席树/离线树状数组)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...

最新文章

  1. php mysql sql mode_Mysql之SQL Mode用法详解_MySQL
  2. python爬虫(四)_urllib2:handle处理器和自定义opener
  3. Tomcat 最新版安装与使用手册,tomcat更改端口号方法,tomcat控制台乱码问题解决方法
  4. TestNG方法測试及注意要点 代码及配置具体解释(解决testng方法不运行问题)
  5. UC伯克利摘最佳论文、Hugging Face获最佳demo,EMNLP 2020奖项公布
  6. Spark任务提交后是如何完成提交过程的?源码解析!
  7. POE交换机产品如何设计防雷保护?
  8. codeigniter_如何在浏览器中查看CodeIgniter日志文件
  9. C中关于存储类的理解
  10. 红橙Darren视频笔记 界面优化与屏幕适配(上)
  11. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛——F题 成绩查询ing
  12. java 覆盖文件_java复制文件(如果目标文件存在,是否覆盖)
  13. plsqldev显示语言有问题
  14. DreamWeaver CC网页设计与制作
  15. PowerShell,AnkhSVN和Subversion
  16. 解决TypeError: conv2d() received an invalid combination of arguments
  17. 阿里巴巴矢量图标引用问题
  18. 切比雪夫插值多项式在非线性电路中的应用与比较
  19. cuda性能分析工具
  20. 深入学习ArduinoJson库 V5版本

热门文章

  1. 乌合之众-大众心理研究(十四)
  2. 频率响应、零极点和系统稳定性
  3. 二套模板的小说网站源码 带采集功能
  4. keil5“魔法棒”配置
  5. 单变量微积分笔记——积分的应用
  6. easyExcel自定义格式转换
  7. 给你安利几款好用的音频转换ogg格式的软件
  8. 关于使用工具包,应用程序中发生了无法处理的异常。如果单击“继续”,应用程序忽略错误尝试继续运行。点击退出,应用程序将会“关闭”。异常来自HRESULT:0x80040228的错误问题!
  9. linux迷宫游戏,宝藏迷宫逃离
  10. zset获取指定score_redis zset更新score redis学习笔记5 - Redis - 服务器之家