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

Problem Description
Chika gives you an integer sequence a1,a2,…,an and m tasks. For each task, you need to answer the number of “friendly pairs” in a given interval.

friendly pair: for two integers ai and aj, if i<j and the absolute value of ai−aj is no more than a given constant integer K, then (i,j) is called a “friendly pair”.A friendly pair (i,j) in a interval [L,R] should satisfy L≤i<j≤R.

Input
The first line contains 3 integers n (1≤n≤27000), m (1≤m≤27000) and K (1≤K≤109), representing the number of integers in the sequence a, the number of tasks and the given constant integer.
The second line contains n non-negative integers, representing the integers in the sequence a. Every integer of sequence a is no more than 109.
Then m lines follow, each of which contains two integers L, R (1≤L≤R≤n). The meaning is to ask the number of “friendly pairs” in the interval [L,R]。

Output
For each task, you need to print one line, including only one integer, representing the number of “friendly pairs” in the query interval.

Sample Input
7 5 3
2 5 7 5 1 5 6
6 6
1 3
4 6
2 4
3 4

Sample Output
0
2
1
3
1
题意:给出n个数(用数组a存储),和m组询问区间(L,R),还有一个K,对于每一组询问,给出这个区间中满足(a[i] - a[j])的绝对值不大于K的数对的个数,其中i<j;
思路:挂在莫队的标签上就用莫队咯,但是问题就来了,怎么在区间指针lp,rp转移的时候维护好答案,第一想法便是如果能够在指针转移的时候,我们假设要加入或者移除一个x,只要找出此时区间中和x满足题意的数的个数那么就很好办,直接维护答案就Ok,然后这个问题就和hdu6621有点像了,写主席树来查询一下也就行了,时间复杂度的话,主席树不是log(n)吗,然后我看的一篇莫队论文里面说维护时间尽量O(1),数据弱的时候log(n)跑问题也不大,那就写吧。然后就T了(T^T)。。。而且T得还挺严重的,改了分快的数量都不行.然后看了下题解都是树状数组+莫队过的,还说啥卡常,只能这样做(我吐了,难道主席树+莫队它不香,但是树状数组+莫队代码短是真的香)
但是你以为就这¿对于一个x,要找到对应区间中[x-k,x+k]的数的数量,我们找到x-k,x+k对应离散的区间,并且对于每一个数都要预处理一下,不能再莫队的修改中再lower_bound找,我反正就在这儿一直T

#include<bits/stdc++.h>
#include <cmath>
#include <algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define mod (1000000007)
#define middle (l+r)>>1
#define SIZE 1000000+5
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef long double ld;
const int inf_max = 0x3f3f3f;
const ll Linf = 9e18;
const int maxn = 3e4+10;
const long double E = 2.7182818;
const double eps=0.0001;
using namespace std;
inline int read()
{
    int f=1,res=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { res=res*10+ch-'0' ; ch=getchar(); }
    return f*res;
}
struct QRY
{
    int l,r,id;
    ll ans;
}q[maxn];
const int up = 30000;
int n,m,k,cnt,a[maxn],lsan[maxn],tot,tree[maxn],block,lp,rp,le[maxn],ri[maxn];
ll ret;
inline bool cmp1(QRY a,QRY b) {
    int belonga = (a.l - 1) / block + 1,belongb = (b.l - 1) / block + 1;
    return (belonga == belongb ? a.r < b.r : a.l < b.l);
}
inline bool cmp2(QRY a,QRY b) {
    return a.id < b.id;
}
inline int getpos(int x) {
    return lower_bound(lsan + 1,lsan + 1 + tot,x) - lsan;
}
inline void update(int pos,int val) {
    if(!pos) return ;
    while(pos <= up) {
        tree[pos] += val;
        pos += lowbit(pos);
    }
}
inline ll query(int x) {
    ll res = 0;
    while(x > 0) {
        res += tree[x];
        x -= lowbit(x);
    }
    return res;
}
inline void myremove(int x) {
    update(getpos(x),-1);  //我们要先删除这个数再找  否则就会把自己也算进去。造成多算
    ret -= query(ri[x]) - query(le[x] - 1);
}
inline void add(int x) {
    ret += query(ri[x]) - query(le[x] - 1);
    update(getpos(x),1);  //同理,要先找了再加不然也会多算。
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i = 1; i <= n; ++i) {
        a[i] = read();
        lsan[i] = a[i];
    }
    //离散
    sort(lsan + 1,lsan + 1 + n);
    tot = unique(lsan + 1,lsan + 1 + n) - lsan -1;
    // 分块处理
    block = (int)sqrt(n * 2);
    for(int i = 1;i <= n;++i) {
        le[a[i]] = lower_bound(lsan + 1,lsan + 1 + tot,a[i] - k) - lsan;
        ri[a[i]] = upper_bound(lsan + 1,lsan + 1 + tot,a[i] + k) - lsan - 1;
    }  //预处理一下对于每个数x[x-k,x+k]对应的离散化区间。
    for(int i = 1;i <= m; ++i) {
        q[i].l = read();q[i].r = read();
        q[i].id = i;
    }
    sort(q + 1,q + 1 + m,cmp1);
    // 莫队处理询问
    lp = 1;rp = 0;
    for(int i = 1;i <= m; ++i) {
        if(q[i].l == q[i].r) {
            q[i].ans = 0;
            continue;
        }
        while(lp < q[i].l) myremove(a[lp]),++lp;
        while(lp > q[i].l) --lp,add(a[lp]);
        while(rp > q[i].r) myremove(a[rp]),--rp;
        while(rp < q[i].r) ++rp,add(a[rp]);
        q[i].ans = ret;
    }
    sort(q + 1,q + 1 + m,cmp2);
    for(int i = 1;i <= m; ++i) {
        printf("%lld\n",q[i].ans);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值