首页 > 代码库 > Codeforces Round 261 Div.2 D Pashmak and Parmida's problem --树状数组
Codeforces Round 261 Div.2 D Pashmak and Parmida's problem --树状数组
题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数。i和j符合f(1,i,a[i])>f(j,n,a[j]),求有多少对这样的(i,j).
解法:分别从左到右,由右到左预处理到某个下标为止有多少个数等于该下标,用map维护。
然后树状数组更新每个f(j,n,a[j]),预处理完毕,接下来,从左往右扫过去,每次从树状数组中删去a[i],因为i != j,i不能用作后面的统计,然后统计getsum(inc[a[i]]-1),
(inc表示从左到右),即查询比此时的a[i]小的f(j,n,a[j])个数。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <map>#define lll __int64using namespace std;using namespace __gnu_cxx;#define N 1000007#define M 22int c[N],a[N];map<int,int> inc,des;int n;int lowbit(int x){ return x & (-x);}void modify(int x,int val){ while(x <= n) { c[x] += val; x += lowbit(x); }}int getsum(int x){ int res = 0; while(x > 0) { res += c[x]; x -= lowbit(x); } return res;}int main(){ int i; inc.clear(); des.clear(); memset(c,0,sizeof(c)); scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=n;i>=1;i--) { des[a[i]]++; modify(des[a[i]],1); } lll ans = 0; for(i=1;i<=n;i++) { inc[a[i]]++; modify(des[a[i]],-1); des[a[i]]--; ans += getsum(inc[a[i]]-1); } printf("%I64d\n",ans); return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。