离散化
离散化
应用场景
当数的范围非常大,而用到的数又十分稀疏的时候,使用离散化的方法来处理。
题目
模板题: acwing 802 区间和(vector实现去重和离散化)
假定有一个无限长的数轴,数轴上每个坐标上的数都是0。
现在,我们首先进行 n 次操作,每次操作将某一位置x上的数加c。
接下来,进行 m 次询问,每个询问包含两个整数l和r,你需要求出在区间[l, r]之间的所有数的和。
输入格式
第一行包含两个整数n和m。
接下来 n 行,每行包含两个整数x和c。
再接下里 m 行,每行包含两个整数l和r。
输出格式
共m行,每行输出一个询问中所求的区间内数字和。
数据范围
$ 10 ^ 9 $ ≤ x ≤ $ 10 ^ 9 $
1≤n,m≤$ 10 ^ 5 $
−$10^9$≤l≤r≤$10^9$
−10000≤c≤10000
输入样例:
1 2 3 4 5 6 7
| 3 3 1 2 3 6 7 5 1 3 4 6 7 8
|
输出样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include<iostream> #include<cstdio> #include<vector> #include<algorithm> using namespace std; const int N=300050; int n,m; int a[N],sum[N]; typedef pair<int,int> pii; vector <int> s; vector <pii> add,q; int find(int x) { int l=0,r=s.size()-1; while(l<r) { int mid=(l+r)>>1; if(s[mid]>=x)r=mid; else l=mid+1; } return r+1; } int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) { int x,c; cin>>x>>c; add.push_back({x,c}); s.push_back(x); } for(int i=1;i<=m;i++) { int l,r; cin>>l>>r; q.push_back({l,r}); s.push_back(l); s.push_back(r); } sort(s.begin(),s.end()); s.erase(unique(s.begin(),s.end()),s.end()); for(auto item:add) { int x=find(item.first); a[x]+=item.second; } for(int i=1;i<=s.size();i++) { sum[i]=sum[i-1]+a[i]; } for(auto item:q) { int l=find(item.first),r=find(item.second); cout<<sum[r]-sum[l-1]<<endl; } return 0; }
|
洛谷 P1908逆序对【树状数组做法】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=500050; ll tree[N],b[N]; int n; ll ans=0; struct node { ll val,num; }a[N]; ll lowbit(ll k) { return k&(-k); } void add(ll k) { while(k<=n) { tree[k]+=1; k+=lowbit(k); } } ll getsum(ll k) { ll sum=0; while(k) { sum+=tree[k]; k-=lowbit(k); } return sum; } bool cmp(node x,node y) { if(x.val==y.val) return x.num<y.num; return x.val<y.val; } int main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) { cin>>a[i].val; a[i].num=i; } sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) { b[a[i].num]=i; }
for(int i=n;i>=1;i--) { add(b[i]); ans+=getsum(b[i]-1); } cout<<ans; return 0; }
|
CSDN离散化