201⑨湘潭邀请赛 Chika and Friendly Pairs(HDU6534)

题意:给你一个数组,对于第i个数来说,如果存在一个位置j,使得j>i并且a[j]-k<=a[i]<=a[j]+k,那么这对数就称为好的,有q个询问,问你l到r区间有多少对好的数。

离线询问,想到可以用莫队维护区间,新加入元素(或删除元素)x时要统计区间[x-k,x+k]内的元素个数,想到 可以利用树状数组存元素个数(cnt)(权值数组),区间和就是元素个数,数据<=1e9,因此需要离散化a[i],a[i]+k,a[i]-k,记离散化后对应的数组为p1,p2,p3,每次区间增加下标为i的元素时,用树状数组求(p3[i],p2[i])的元素和,同时update(p1[i],1)。删除元素同理,为了防止询问时统计到自身,需要先更新再询问。

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=27005;
const int maxv=maxn*3;
typedef long long ll;
ll res,ans[maxn];
struct Q{
    ll l,r,id;
}query[maxn];
int h[maxn],a[maxn];
int aa[maxn*3],T[maxn*3];
int p1[maxn],p2[maxn],p3[maxn];
bool cmp(Q a,Q b){
    return (h[a.l]^h[b.l])?a.l<b.l:( (h[a.l]&1)?a.r<b.r:a.r>b.r);
}
int lowbit(int i){
    return i &(-i);
}
void update(int i,int val){
    while(i<=maxv){
        T[i]+=val;
        i+=lowbit(i);
    }
}
int sum(int i){//求区间[1,i]内所有元素的和
    int res=0;
    while(i>0){
        res+=T[i];//从右往左累加求和
        i-=lowbit(i);
    }
    return res;
}
int _query(int l,int r){
    return sum(r)-sum(l-1);
}
inline void insert(int x){
    res+=_query(p3[x],p2[x]);
    update(p1[x],1);
}
inline void erase(int x){
    update(p1[x],-1);
    res-=_query(p3[x],p2[x]);
}
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    int block=sqrt(n);
    for(int i=0;i<=n;i++) h[i]=i/block;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int cnt=0;
    //离散化
    for(int i=1;i<=n;i++){
        aa[++cnt]=a[i];
        aa[++cnt]=a[i]+k;
        aa[++cnt]=a[i]-k;
    }
    sort(aa+1,aa+1+cnt);
    int size=unique(aa+1,aa+1+cnt)-(aa+1);
    for(int i=1;i<=n;i++){
        p1[i]=lower_bound(aa+1,aa+1+size,a[i])-aa;
        p2[i]=lower_bound(aa+1,aa+1+size,a[i]+k)-aa;
        p3[i]=lower_bound(aa+1,aa+1+size,a[i]-k)-aa;
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&query[i].l,&query[i].r);
        query[i].id=i;
    }
    sort(query+1,query+1+m,cmp);
    int l=1,r=0;
    for(int i=1;i<=m;i++){
        Q &q=query[i];
        while(l<q.l)erase(l++);
        while(l>q.l)insert(--l);
        while(r>q.r)erase(r--);
        while(r<q.r)insert(++r);
        ans[q.id]=res;
    }
    for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}

原文地址:https://www.cnblogs.com/ucprer/p/11347991.html

时间: 2024-11-09 04:39:35

201⑨湘潭邀请赛 Chika and Friendly Pairs(HDU6534)的相关文章

Chika and Friendly Pairs(莫队+树状数组+离散化+预处理上下界)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6534 Chika and Friendly Pairs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 160    Accepted Submission(s): 52 Problem Description Chika gives y

Chika and Friendly Pairs(莫队+离散化+树状数组)

Chika and Friendly Pairs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1164    Accepted Submission(s): 421 Problem Description Chika gives you an integer sequence a1,a2,…,an and m tasks. For

HDU - 6534 Chika and Friendly Pairs

这个题其实也是很简单的莫队,题目要求是给一个序列,询问l-r区间内部,找到有多少对答案满足 i < j 并且 | a[ i ] -a[ j ] | <=k 也就是有多少对,满足差值小于k的个数. 把这个式子展开,其实就是-k<= a[ i ] -a [ j ] <= k 也就是  a[ j ] -k <= a[ i ] <= a[ j ] + k,也就是说,对于某个 j 位置,我们需要在询问的区间内,找到 i < j 并且在[ a[j] -k ,a[j] +k ]

2018年湘潭邀请赛

题目链接: http://acm.hdu.edu.cn/listproblem.php?vol=53 A题: 题意: 总共有sum(a[i])篇文章,文章含有i条引用的文章数是ai,求最大的h使得最少有h篇文章含有至少h条引用. 思路: 二分,不过一开始把i和ai的含义读反wa了几发. 代码实现如下: 1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <queue> 5 #incl

[题解]2018湘潭邀请赛

A.Easy h-index 题目描述 The h-index of an author is the largest h where he has at least h papers with citations not less than h.Bobo has published many papers. Given a0, a1, a2 ,..., an which means Bobo has published a i papers with citations exactly i ,

2014湘潭邀请赛 C题 湘大OJ 1205 Range (单调栈)

Problem Description For an array, the range function is defined below: Range(A)=Max(A)-Min(A)+1; For example, suppose A={1,2,3,4,5}, then Range(A)=5-1+1=5. Now, given an array A(length≤100000), you are going to calcalute the sum of all subarray's ran

XTU 1261 - Roads - [最小割][2017年湘潭邀请赛(江苏省赛)B题]

之前在网上搜了一个下午没搜到这道题的题解,然后同时又对着叉姐写的两行字题解看了一个下午: 虽然基本上已经知道了这题的思路,但愣是因为自己代码实现起来太繁复,外加不确定正确性,没敢码-- 但是一道题肝了一下午没肝出来,就要放弃的话,怕是太扎心了,忍不住就跑去ICPCCamp.Post问叉姐了(https://post.icpc-camp.org/d/715-2017-b-roads) 看了叉姐的对于我的几个问题的回复,我总算肯定了我的思路,而且叉姐还在下面给了标程,当时可以说心情非常愉悦: 听起来

[CCPC2017]湘潭邀请赛

题目链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/index/p/14/ D.模拟,按照原图每一个字符变成一个a*b的矩阵构造新矩阵. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 111; 5 int n, m, a, b; 6 char G[maxn][maxn]; 7 char GG[maxn][maxn]; 8 9 10 in

湘潭邀请赛——Alice and Bob

Alice and Bob Accepted : 133   Submit : 268 Time Limit : 1000 MS   Memory Limit : 65536 KB  Problem Description The famous "Alice and Bob" are playing a game again. So now comes the new problem which need a person smart as you to decide the winn