HDU 5273 Dylans loves sequence【 树状数组 】

题意:给出n个数,再给出q个询问,求L到R的逆序对的个数

先自己写的时候,是每次询问都重新插入来求sum(r)-sum(l)

果断T

后来还是看了别人的代码----

预处理一下,把所有可能的区间的询问都求出来(1000*1000), 然后询问就是O(1)了

然后想自己这样写超时,是因为询问太多了----

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include <cmath>
 5 #include<stack>
 6 #include<vector>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<algorithm>
11 using namespace std;
12
13 typedef long long LL;
14 const int INF = (1<<30)-1;
15 const int mod=1000000007;
16 const int maxn=1005;
17
18 int a[maxn];
19 int c[maxn];//树状数组
20 int n,m;
21 int ans[maxn][maxn];
22
23 struct node{
24     int x,id;
25 }p[maxn];
26
27 int cmp(node n1,node n2){
28     return n1.x < n2.x;
29 }
30
31 int lowbit(int x){ return x &(-x);}
32
33 int sum(int x){
34     int ret=0;
35     while(x>0){
36         ret += c[x];x-=lowbit(x);
37     }
38     return ret;
39 }
40
41 void add(int x,int d){
42     while(x<=n){
43         c[x]+=d;x+=lowbit(x);
44     }
45 }
46
47 int main(){
48     while(scanf("%d %d",&n,&m) != EOF){
49         memset(c,0,sizeof(c));
50         memset(a,0,sizeof(a));
51         memset(ans,0,sizeof(ans));
52         for(int i=1;i<=n;i++) {
53             scanf("%d",&p[i].x);
54             p[i].id=i;
55         }
56         sort(p+1,p+n+1,cmp);
57         for(int i=1,j=0;i<=n;i++){
58             if(i==1||p[i].x != p[i-1].x) j++;
59             a[p[i].id]=j;
60         }
61
62     //    for(int i=1;i<=n;i++)
63     //    printf("a[%d]=%d\n",i,a[i]);
64
65         for(int i=1;i<=n;i++){
66             memset(c,0,sizeof(c));
67             int res=0;
68             for(int j=i;j<=n;j++){
69                 res+=(j-i)-sum(a[j]);
70                 add(a[j],1);
71                 ans[i][j] = res;
72             }
73         }
74
75         while(m--){
76             int l,r;
77             scanf("%d %d",&l,&r);
78             printf("%d\n",ans[l][r]);
79         }
80     }
81     return 0;
82 } 

时间: 2024-10-09 23:26:12

HDU 5273 Dylans loves sequence【 树状数组 】的相关文章

hdu 5273 Dylans loves sequence 逆序数简单递推

Dylans loves sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5273 Description Dylans得到了N个数a[1]...a[N].有Q个问题,每个问题形如(L,R)他需要求出L−R这些数中的逆序对个数.更加正式地,他需要求出二元组(x,y)的个数,使得L≤x,y≤R且x<y且a[x]>a[y] Input 第一行有两个数N和Q

hdu 5273 Dylans loves sequence(区间逆序对数-莫队算法)

n<=1000,q<=100000,求区间内逆序对数,从[l,r]显然可以log(n)的时间内移动到[l-1,r],[l+1,r],[l,r-1],[l,r+1],那么就可以用莫队进行离线 复杂度大概是O(n*sqrt(n)*log2(n)),不过可以暴力枚举起点,然后向后统计,然后O(1)回答,不过n再大就无法解决了,这个即使是n<=1e5也可以很快得到答案,开-o优化,1e6也可以很快得到答案 #include<bits/stdc++.h> using namespace

HDU 5273 Dylans loves sequence(区间DP)

Dylans loves sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 114    Accepted Submission(s): 59 Problem Description Dylans is given N numbers a[1]....a[N] And there are Q questions. E

HDU 5057 Argestes and Sequence --树状数组(卡内存)

题意:给n个数字,每次两种操作: 1.修改第x个数字为y. 2.查询[L,R]区间内第D位为P的数有多少个. 解法:这题当时被卡内存了,后来看了下别人代码发现可以用unsigned short神奇卡过,于是学习了. 这种区间求和的问题很容易想到树状数组,根据第i位为j(i<10,j<10)建立100棵树状数组(由于内存100*100000被卡,且看到个数,即c[10][10][100000]的值最多为100000,那么最多分两个unsigned short (0~65535),记录一下就可以了

hdu 5273 Dylans loves sequence

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5273 bestcoder round#45 1002 题目大意: 给出一个有n个数的任意序列,问[r,l]区间内一共有多少对倒置数? 解题思路: 由于1<=n<=1000,所以想怎么做怎么做,当时不知道怎么了,思路不错,但是就是代码wa. 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h&

HDU 5273 Dylans loves sequence (逆序对,暴力)

题意:给定一个序列,对于q个询问:(L,R)之间有几个逆序对?序列元素个数上限1000,q上限10万.仅1测试例子. 思路: 先分析: [L,R]的逆序对数量可以这么算,假设L<=K<R,将区间拆成两部分,那么[L,k]中的逆序对要算上, (k,R]中的逆序对也要算上,还有一些逆序对假设为(l,r),l在左部分,r在右部分.则应该是3部分来构成,设3部分为A,B,C,那么ans=A+B+C . 而如果将k移到最右边,比如k=R-1,那么区间拆成[L,k]和(K,R],而(K,R]其实就只有R一

HDU 5196 DZY Loves Inversions(树状数组,二分)

这题之前CC做过类似的,思路如官方题解. 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 100005; typedef long long ll; int n, m; ll q; struct Hash { int v, id; void read(int id) { scanf("%d", &

hdu 3015 Disharmony Trees (离散化+树状数组)

Disharmony Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 663    Accepted Submission(s): 307 Problem Description One day Sophia finds a very big square. There are n trees in the square. T

HDU 2852 KiKi&#39;s K-Number (树状数组 &amp;&amp; 二分)

题意:给出对容器的总操作次数n, 接下来是这n个操作.这里对于一个容器提供三种操作, 分别是插入.删除和查找.输入0  e表示插入e.输入1  e表示删除e,若元素不存在输出No Elment!.输入2  e  k表示查找比e大且第k大的数, 若不存在则输出Not Find! 分析:这里考虑树状数组做的原因是在第三个操作的时候, 只要我们记录了元素的总数, 那通过求和操作, 便能够高效地知道到底有多少个数比现在求和的这个数要大, 例如 tot - sum(3)就能知道整个集合里面比3大的数到底有