zoukankan      html  css  js  c++  java
  • HDU

     这个题其实也是很简单的莫队,题目要求是给一个序列,询问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 ] 范围中的数的个数,这个其实可以通过树状数组区间查询即可。

    但是对于k来说,太大了,树状数组也开不下,所以我们要进行离散化,把a[i],a[i]+k,a[i]-k位置存下来即可(老套路了)保证每个位置都能找得到,然后区间查询即可,然后每次算贡献即可。

      

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int maxx = 2e5+6;
    int block;
    int a[maxx];
    std::vector<int>vx;
    int sum[maxx];
    int ans[maxx];
    int num;
    int n,m,k;
    struct node{
      int l,r;
      int id;
      friend bool operator < (const node &a,const node &b){
          if(a.l/block==b.l/block){
              return a.r<b.r;
          }
          return a.l/block<b.l/block;
      }
    }q[maxx];
    int low[maxx];
    int up[maxx];
    int p[maxx];
    int lowbit(int x){
      return x&(-x);
    }
    void add(int x,int w){
       for(int i=x;i<=3*n;i+=lowbit(i)){
         sum[i]+=w;
       }
       return ;
    }
    int getsum(int x){
       int s=0;
       for(int i=x;i;i-=lowbit(i)){
           s+=sum[i];
       }
       return s;
    }
    void add(int x){
       num+=getsum(up[x])-getsum(low[x]-1);
       add(p[x],1);
    }
    void del(int x){
       add(p[x],-1);
       num-=getsum(up[x])-getsum(low[x]-1);
    }
    int main(){
      while(~scanf("%d%d%d",&n,&m,&k)){
         block=sqrt(n);
         memset(sum,0,sizeof(sum));
         memset(ans,0,sizeof(ans));
         vx.clear();
         ///绝对值小于等于K
         for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            vx.push_back(a[i]);
            vx.push_back(a[i]+k);
            vx.push_back(a[i]-k);
         }
         num=0;
         sort(vx.begin(),vx.end());
         vx.erase(unique(vx.begin(),vx.end()),vx.end());
         int sz=vx.size();
         for(int i=1;i<=n;i++){
            p[i]=lower_bound(vx.begin(),vx.end(),a[i])-vx.begin()+1;
            low[i]=lower_bound(vx.begin(),vx.end(),a[i]-k)-vx.begin()+1;
            up[i]=lower_bound(vx.begin(),vx.end(),a[i]+k)-vx.begin()+1;
         }
         for(int i=1;i<=m;i++){
           scanf("%d%d",&q[i].l,&q[i].r);
           q[i].id=i;
         }
         sort(q+1,q+1+m);
         int l=1,r=0;
         num=0;
         for(int i=1;i<=m;i++){
            while(l<q[i].l)del(l),l++;
          //  cout<<num<<" ";
            while(l>q[i].l)l--,add(l);
          //  cout<<num<<" ";
            while(r<q[i].r)r++,add(r);
           // cout<<num<<" ";
            while(r>q[i].r)del(r),r--;
          //  cout<<num<<" "<<endl;
            ans[q[i].id]=num;
         }
        for(int i=1;i<=m;i++){
            printf("%d
    ",ans[i]);
        }
      }
      return 0;
    }
  • 相关阅读:
    Android之绚丽的图片游览效果--有点像W7效果,透明的倒影,层叠的图片,渐变的颜色透明度
    小程序自定义弹出框
    从零学React Native之04自定义对话框
    ajax的content-download时间过慢问题的解决与思考
    小程序
    使用自定义视图的AlertDialog
    Android浮动按钮
    android 实现微信分享多张图片的功能
    AndroidUI多线程网络请求更新导致BUG
    ==比较时的坑
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11530842.html
Copyright © 2011-2022 走看看