1 solutions
-
0
思路
很显然一眼看过去就是一道很经典的二维偏序问题,我们通过对询问存储下来然后升序排序,通过线段树或者树状数组更新并离线询问即可
Code
#include<bits/stdc++.h> #include<ctime> #include<cstdlib> using namespace std; #define ll long long const int N = 5e5+10; ll tree[N],a[N],ans[N],vis[N]; ll n,m; struct Node { int pos,l,r; }V[N]; ll lowbit(ll x) { return -x & x; } void updata(ll x,ll k) { while(x <= n) { tree[x] += k; x += lowbit(x); } } ll query(ll x){ ll ans = 0; while(x) { ans += tree[x]; x -= lowbit(x); } return ans; } int main() { scanf("%lld%lld",&n,&m); for(int i = 1;i <= n; ++i) { scanf("%lld",&a[i]); } ll l,r; for(ll i = 1;i <= m; ++i) { scanf("%lld%lld",&l,&r); V[i].l = l; V[i].r = r; V[i].pos = i; } sort(V+1,V+1+m,[](Node a,Node b){return a.r == b.r?a.l < b.l:a.r < b.r;}); ll loc = 1; for(ll i = 1;i <= m; ++i) { for(ll j = loc;j <= V[i].r; ++j) { if(vis[a[j]]) updata(vis[a[j]],-a[j]); vis[a[j]] = j; updata(j,a[j]); } loc = V[i].r + 1; ans[V[i].pos] = query(V[i].r) - query(V[i].l - 1); } for(ll i = 1;i <= m; ++i) { printf("%lld\n",ans[i]); } return 0; }
- 1
Information
- ID
- 269
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 6
- Tags
- # Submissions
- 34
- Accepted
- 4
- Uploaded By