BZOJ 3289 莫队 树状数组
2016-01-25 18:10
323 查看
BZOJ 3289
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=3289
题意:
问[L,R]区间最少交换几次相邻数字使得整个序列有序。
思路:
统计逆序对,用树状数组。然后跑一遍莫队。
离散化部分容易超时,所以直接修改了数组。
源码:
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=3289
题意:
问[L,R]区间最少交换几次相邻数字使得整个序列有序。
思路:
统计逆序对,用树状数组。然后跑一遍莫队。
离散化部分容易超时,所以直接修改了数组。
源码:
[code]#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <string> #include <algorithm> #include <iostream> #include <vector> #include <map> using namespace std; #define LL unsigned int const int MAXN = 50000 + 5; int tr[MAXN * 2]; ///tree array int cnt; int lowbit(int u){return u & -u;} void update(int u, int v) { for(; u <= cnt ; u += lowbit(u)){ tr[u] += v; } } LL query(int u) { LL ans = 0; for(; u; u -= lowbit(u)) { ans += tr[u]; } return ans; } int data[MAXN]; int pos[MAXN]; int blocksize; int n, m; struct Q { int l, r, id; }q[MAXN]; bool cmp(Q a, Q b) { if(pos[a.l] == pos[b.l]) return a.r < b.r; return a.l < b.l; } int tt[MAXN]; LL res[MAXN]; map<int,int>mm; int main() { // freopen("BZOJ 3289.in", "r", stdin); while(scanf("%d", &n) != EOF){ blocksize = sqrt(1.0 * n); for(int i = 1 ; i <= n ; i++) scanf("%d", &data[i]), tt[i] = data[i], pos[i] = (i - 1) / blocksize; sort(tt + 1 , tt + 1 + n); mm.clear(); cnt = 0; for(int i = 1 ; i <= n ; i++){ ///离散化 if(mm[tt[i]] == 0) mm[tt[i]] = ++cnt; } for(int i = 1 ; i <= n ; i++) data[i] = mm[data[i]]; // for(int i = 1 ; i <= n ; i++) printf("data[i] = %d, mm = %d\n", data[i], mm[data[i]]); // printf("cnt = %d\n", cnt); // system("pause"); scanf("%d", &m); for(int i = 0 ; i < m ; i++) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i; sort(q, q + m, cmp); int curr = 0; int curl = 1; memset(tr, 0, sizeof(tr)); LL ans = 0; for(int i = 0 ; i < m ; i++){ for(int j = curr + 1 ; j <= q[i].r ; j++) update(data[j], 1), ans += j - curl + 1 - query(data[j]); // printf("ans = %I64d\n", ans); for(int j = curr ; j > q[i].r ; j--) update(data[j], -1), ans -= j - curl - query(data[j]); // printf("ans = %I64d\n", ans); curr = q[i].r; for(int j = curl ; j < q[i].l ; j++) update(data[j], -1), ans -= query(data[j] - 1); // printf("ans = %I64d\n", ans); for(int j = curl - 1 ; j >= q[i].l ; j--) update(data[j], 1), ans += query(data[j] - 1); // printf("ans = %I64d\n", ans); curl = q[i].l; res[q[i].id] = ans; // printf("l = %d, r = %d, ans = %I64d\n", q[i].l, q[i].r, ans); } for(int i = 0 ; i < m ; i++) printf("%d\n", res[i]); } return 0; }
相关文章推荐
- HTML5设计原理
- 初探Unity与android的交互
- 常用资料记录(按本人需要)
- 蓝牙学习之旅——低功耗蓝牙之频带和通道
- js动态创建Form表单并提交
- Java基础学习9_继承
- Android 去掉标题和状态栏 达到全屏显示
- 怎样将Oracle11g导出的dmp文件怎样导入到Oracle10g中?
- scanf的疑惑 待解决
- android:windowSoftInputMode
- 在电脑上调试手机上的webview
- Javascript 函数声明及使用
- 很全的AlartView和AlertViewController用法
- iOS中使用AutoLayout动态调整Cell高度
- 敏捷术语
- 自学Python十二 战斗吧Scrapy!
- 验证码生成
- Android网络解析
- 蔡康永--说话之道(一)
- Android之Handler详解