bzoj 3289: Mato的文件管理 莫队+线段树

题目链接

给一些询问,每个询问给出区间[L, R] , 求这段区间的逆序数。

先分块排序, 然后对于每次更改, 如果是更改L, 那么应该查询区间内比他小的数的个数, 如果更改R, 查区间内比他大的数的个数。

记得离散化。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define pb(x) push_back(x)
  4 #define ll long long
  5 #define mk(x, y) make_pair(x, y)
  6 #define lson l, m, rt<<1
  7 #define mem(a) memset(a, 0, sizeof(a))
  8 #define rson m+1, r, rt<<1|1
  9 #define mem1(a) memset(a, -1, sizeof(a))
 10 #define mem2(a) memset(a, 0x3f, sizeof(a))
 11 #define rep(i, a, n) for(int i = a; i<n; i++)
 12 #define ull unsigned long long
 13 typedef pair<int, int> pll;
 14 const double PI = acos(-1.0);
 15 const double eps = 1e-8;
 16 const int mod = 1e9+7;
 17 const int inf = 1061109567;
 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
 19 const int maxn = 50005;
 20 int a[maxn], ans[maxn], sum[maxn<<2], b[maxn];
 21 void pushUp(int rt) {
 22     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
 23 }
 24 void update(int p, int l, int r, int rt, int val) {
 25     if(l == r) {
 26         sum[rt]+=val;
 27         return ;
 28     }
 29     int m = l+r>>1;
 30     if(p<=m)
 31         update(p, lson, val);
 32     else
 33         update(p, rson, val);
 34     pushUp(rt);
 35 }
 36 int query(int L, int R, int l, int r, int rt) {
 37     if(R<L)
 38         return 0;
 39     if(L<=l&&R>=r) {
 40         return sum[rt];
 41     }
 42     int m = l+r>>1, ret = 0;
 43     if(L<=m)
 44         ret += query(L, R, lson);
 45     if(R>m)
 46         ret += query(L, R, rson);
 47     return ret;
 48 }
 49 struct node
 50 {
 51     int block, r, l, id;
 52     bool operator < (node a)const
 53     {
 54         if(block == a.block)
 55             return r<a.r;
 56         return block<a.block;
 57     }
 58 }q[maxn];
 59 int main()
 60 {
 61     int n, m;
 62     while(~scanf("%d", &n)) {
 63         for(int i = 1; i<=n; i++) {
 64             scanf("%d", &a[i]);
 65             b[i-1] = a[i];
 66         }
 67         sort(b, b+n);
 68         int cnt = unique(b, b+n)-b;
 69         for(int i = 1; i<=n; i++)
 70             a[i] = lower_bound(b, b+cnt, a[i])-b+1;
 71         scanf("%d", &m);
 72         int BLOCK = sqrt(n*1.0);
 73         for(int i = 0; i<m; i++) {
 74             scanf("%d%d", &q[i].l, &q[i].r);
 75             q[i].id = i;
 76             q[i].block = q[i].l/BLOCK;
 77         }
 78         mem(sum);
 79         sort(q, q+m);
 80         int tmp = 0;
 81         for(int i = q[0].l; i<=q[0].r; i++) {
 82             tmp += query(a[i]+1, n, 1, n, 1);
 83             update(a[i], 1, n, 1, 1);
 84         }
 85         ans[q[0].id] = tmp;
 86         for(int i = 1; i<m; i++) {
 87             for(int j = q[i-1].l; j<q[i].l; j++) {
 88                 update(a[j], 1, n, 1, -1);
 89                 tmp -= query(1, a[j]-1, 1, n, 1);
 90             }
 91             for(int j = q[i-1].l-1; j>=q[i].l; j--) {
 92                 tmp += query(1, a[j]-1, 1, n, 1);
 93                 update(a[j], 1, n, 1, 1);
 94             }
 95             for(int j = q[i-1].r+1; j<=q[i].r; j++) {
 96                 tmp += query(a[j]+1, n, 1, n, 1);
 97                 update(a[j], 1, n, 1, 1);
 98             }
 99             for(int j = q[i-1].r; j>q[i].r; j--) {
100                 update(a[j], 1, n, 1, -1);
101                 tmp -= query(a[j]+1, n, 1, n, 1);
102             }
103             ans[q[i].id] = tmp;
104         }
105         for(int i = 0; i<m; i++) {
106             printf("%d\n", ans[i]);
107         }
108     }
109     return 0;
110 }
时间: 2024-11-01 15:59:21

bzoj 3289: Mato的文件管理 莫队+线段树的相关文章

BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Discuss] Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mat

bzoj 3289: Mato的文件管理 莫队+树状数组

3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mato有一个习惯,他总是从文件大小从小到大看资料.他先

【BZOJ3289】Mato的文件管理 莫队算法+树状数组

[BZOJ3289]Mato的文件管理 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mato有一个习惯,他总是从文件大小从小到大看资料.他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序.排序程序可以在1单位时间内交换2个相邻的文件(因为加密

BZOJ 3289 Mato的文件管理(莫队+离散化求逆序数)

3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MB Submit: 2171  Solved: 891 [Submit][Status][Discuss] Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.M

BZOJ 3289 Mato的文件管理(莫队+树状数组)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3289 [题目大意] 求静态区间逆序对. [题解] 我们对查询进行莫队操作,对于区间的删改我们可以计算出改变量对于逆序对的贡献, 利用树状数组维护即可. [代码] #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> const int N=50100;

BZOJ3289[JZYZOJP2018]: Mato的文件管理 莫队+树状数组+离散化

        描述 Description     Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的,只能用Mato自己写的程序才能访问.Mato每天随机选一个区间[l,r],他今天就看编号在此区间内的这些资料.Mato有一个习惯,他总是从文件大小从小到大看资料.他先把要看的文件按编号顺序依次拷贝出来,再用他写的排序程序给文件大小排序.排序程序可以在1单位时间内交换2个相邻的文件(因为加密需要,不能

BZOJ 3289 Mato的文件管理

莫队+BIT. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define maxn 50050 using namespace std; int n,m,a[maxn],hash[maxn],tot=0,ans=0,pos[maxn],block,t[maxn]; struct query { int l,r,

CF633H Fibonacci-ish II(莫队+线段树)

温馨提示:本题十分卡常数,我手动开O2才过的.而数据范围不伦不类的n<=30000,常数小的O(n2)居然比O(n√nlogn)跑得快…… 考虑插进去一个元素对答案产生的影响.原本数列为Σa[i]f[i],其中1<=i<=n,然后考虑在k位置插入a[0],答案显然是a[1]f[1]+a[2]f[2]+...+a[0]f[k]+a[k]f[k+1]+...+a[n]f[n+1],然后直接区间加斐波那契数显然是不可能的.这时候要向后转移斐波那契数列,(a,b)->(a+b,a)->

【BZOJ】3289: Mato的文件管理(莫队算法+树状数组)

http://www.lydsy.com/JudgeOnline/problem.php?id=3289 很裸的莫队... 离线了区间然后分块排序后,询问时搞搞就行了. 本题中,如果知道$[l, r]$后,考虑如何转移$[l, r+1]$,发现就是$a[r+1]$的颜色在这个区间的排名,然后$r-l+1-排名$就是需要移动的次数. 那么本题中因为只需要裸的排名,所以可以考虑用bit,即离散后搞. 然后就行了 #include <cstdio> #include <cstdio> #