来源:http://acm.hdu.edu.cn/showproblem.php?pid=3450
题意:给一些数,问有多少集合,满足相邻的数之间的差的绝对值小于d。
思路:树状数组,找出上界和下界后,和HDU 2227 一样。找上界和下界的方法为二分。
代码:
#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> using namespace std; const int N = 100010; const int mod = 9901; struct dit{ int id,value,xuhao; }dd[N],tempdd[N]; int cnt[N],dp[N]; bool cmp(dit a,dit b){ return a.value < b.value; } int binary_search(int x,int lp,int rp){ int mid = 0,ans = 1; while(lp <= rp){ mid = (lp + rp) / 2; if(tempdd[mid].value > x) rp = mid - 1; else{ ans = mid; lp = mid + 1; } } return ans; } int binary_search2(int x,int lp,int rp){ int ans = 1; while(lp <= rp){ int mid = (lp + rp) / 2; if(tempdd[mid].value >= x){ rp = mid - 1; ans = mid; } else lp = mid + 1; } return ans; } int lowbit(int x){ return x & (-x); } int sum(int x){ int s = 0; while(x > 0){ s += cnt[x]; if(s >= mod) s = s % mod; x -= lowbit(x); } return s; } void update(int x,int add){ while(x < N){ cnt[x] += add; if(cnt[x] >= mod) cnt[x] = cnt[x] % mod; x += lowbit(x); } } int Bin(int x,int lp,int rp){ while(lp <= rp){ int mid = (lp + rp) >> 1; if(tempdd[mid].value == x) return mid; else if(tempdd[mid].value < x) lp = mid + 1; else rp = mid - 1; } return -1; } int main(){ //freopen("1.txt","r",stdin); int n,d; while(scanf("%d%d",&n,&d) != EOF){ memset(cnt,0,sizeof(cnt)); memset(dp,0,sizeof(dp)); for(int i = 1; i <= n; ++i){ scanf("%d",&dd[i].value); dd[i].id = i; tempdd[i] = dd[i]; } sort(tempdd+1,tempdd+n+1,cmp); int k = tempdd[1].id; int total = 0; for(int i = 1; i <= n; ++i){ if(tempdd[i].value != tempdd[i-1].value || i == 1){ tempdd[++total].value = tempdd[i].value; } } int ans = 0; for(int i = 1; i <= n; ++i){ int id = Bin(dd[i].value,1,total); int x = dd[i].value - d; int y = dd[i].value + d; int xid = 0,yid = 0; xid = binary_search2(x,1,total); yid = binary_search(y,1,total); int s1 = (sum(yid) - sum(xid - 1)); if(s1 < 0) s1 += mod; if(s1 >= mod) s1 = s1 % mod; ans = ans + s1 + 1; if(ans >= mod) ans = ans % mod; update(id,(s1 + 1)%mod); } printf("%d\n",((ans - n) % mod + mod ) % mod); } return 0; }