C - Chika and Friendly Pairs HDU - 6534 (莫队)

题目链接:

https://cn.vjudge.net/problem/HDU-6534

题目大意:

给你n,m,k。然后输入n个数,m个区间。然后问你每个区间满足|a[i]- a[j]|<=k的个数(i<=j)。

具体思路:

莫队处理每个区间,具体查询的时候通过树状数组查询。

AC代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 # define ll long long
  4 const int maxn = 2e6+100;
  5 int n,m,k,block;
  6 struct Point
  7 {
  8     int upp,low,val,now_pos;
  9 } a[maxn];
 10 struct node
 11 {
 12     int st,ed,id;
 13     node() {}
 14     node(int xx,int yy,int zz)
 15     {
 16         st=xx,ed=yy,id=zz;
 17     }
 18     bool friend operator <(node t1,node t2)
 19     {
 20         if(t1.st/block!=t2.st/block)
 21             return t1.st/block < t2.st/block;
 22         return t1.ed/block<t2.ed/block;
 23     }
 24 } q[maxn];
 25 int ans[maxn];
 26 vector<int>sto;
 27 int get_lower(int num)
 28 {
 29     return lower_bound(sto.begin(),sto.end(),num)-sto.begin()+1;
 30 }
 31 int get_upper(int num)
 32 {
 33     return upper_bound(sto.begin(),sto.end(),num)-sto.begin();// 注意这里是lower_bound 
 34 }
 35 int tree[maxn];
 36 int sz;
 37 int lowbit(int t)
 38 {
 39     return t&-t;
 40 }
 41 void add(int pos,int type)
 42 {
 43     while(pos<=sz)
 44     {
 45         tree[pos]+=type;
 46         pos+=lowbit(pos);
 47     }
 48 }
 49 int ask(int pos)
 50 {
 51     int num=0;
 52     if(!pos)
 53         return 0;
 54     while(pos)
 55     {
 56         num+=tree[pos];
 57         pos-=lowbit(pos);
 58     }
 59     return num;
 60 }
 61 void solve()
 62 {
 63     int num=0;
 64     int l=1,r=0;
 65     for(int i=1; i<=m; i++)
 66     {
 67         while(l<q[i].st)
 68         {
 69             add(a[l].now_pos,-1);
 70             num-=ask(a[l].upp)-ask(a[l].low-1);
 71             l++;
 72         }
 73         while(l>q[i].st)
 74         {
 75             l--;
 76             num+=ask(a[l].upp)-ask(a[l].low-1);
 77             add(a[l].now_pos,1);
 78         }
 79         while(r<q[i].ed)
 80         {
 81             r++;
 82             num+=ask(a[r].upp)-ask(a[r].low-1);
 83             add(a[r].now_pos,1);
 84         }
 85         while(r>q[i].ed)
 86         {
 87             add(a[r].now_pos,-1);
 88             num-=ask(a[r].upp)-ask(a[r].low-1);
 89             r--;
 90         }
 91         ans[q[i].id]=num;
 92     }
 93 }
 94 int main()
 95 {
 96     scanf("%d %d %d",&n,&m,&k);
 97     for(int i=1; i<=n; i++)
 98     {
 99         scanf("%d",&a[i].val);
100         sto.push_back(a[i].val);
101     }
102     sort(sto.begin(),sto.end());
103     sto.erase(unique(sto.begin(),sto.end()),sto.end());// 离散化
104     sz=sto.size();
105     for(int i=1; i<=n; i++)
106     {
107         a[i].now_pos=get_lower(a[i].val);// 预处理出每个点的能到达的范围
108         a[i].low=get_lower(a[i].val-k);
109         a[i].upp=get_upper(a[i].val+k);
110     }
111     int st,ed;
112     for(int i=1; i<=m; i++)
113     {
114         scanf("%d %d",&st,&ed);
115         q[i]=node(st,ed,i);
116     }
117     block=(int)(sqrt(n));
118     sort(q+1,q+m+1);
119     solve();
120     for(int i=1; i<=m; i++)
121     {
122         printf("%d\n",ans[i]);
123     }
124     return 0;
125 }

猜你喜欢

转载自www.cnblogs.com/letlifestop/p/10988167.html