题意:问有多少个合法区间。
分析:对于[l,r],枚举右区间r,获取合法的l的区间。当增加一个元素Ai,原来合法的区间就会变不合法,要删掉,同时又会新增一个合法的区间,要插入。
例如,当x=2,对于元素 Ai其出现的位置为:1 2 3, 当新增位置4又出现Ai时,那么原来[1+1,2]的区间不合法,删掉。然后区间[2+1,3],插入。
/************************************************ Author :DarkTong Created Time :2016/7/18 22:08:12 File Name :e.cpp *************************************************/ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <cstdlib> #include <ctime> #define INF 0x3f3f3f3f #define esp 1e-9 typedef long long LL; using namespace std; const int maxn = 100000 + 100; map<int, vector<int> > cor; int a[maxn]; struct Node { int l, r, f; LL d; }st[maxn<<4]; void Build(int x, int L, int R) { st[x].l=L; st[x].r=R; st[x].d=st[x].f=0; if(L+1>=R) return; int m = (L+R)>>1; Build(x<<1, L, m); Build(x<<1|1, m, R); } void pushup(int x) { if(st[x].f) st[x].d = st[x].r-st[x].l; else st[x].d = st[x<<1].d + st[x<<1|1].d; } void pushdown(int x) { st[x<<1].f+=st[x].f; st[x<<1|1].f+=st[x].f; st[x].f=0; } void Update(int x, int L, int R, int d) { if(L<=st[x].l&&st[x].r<=R) { st[x].f+=d; pushup(x); return; } // pushdown(x); int m=(st[x].l+st[x].r)>>1; if(L<m) Update(x<<1, L, R, d); if(m<R) Update(x<<1|1, L, R, d); pushup(x); } int main() { int ca, n, x; scanf("%d", &ca); while(ca--) { scanf("%d%d", &n, &x); LL ans = 0; Build(1, 0, n); cor.clear(); for(int i=0;i<n;++i) scanf("%d", &a[i]); for(int i=0;i<n;++i) { if(cor.count(a[i])==0) cor[a[i]].push_back(-1); cor[a[i]].push_back(i); int si = cor[a[i]].size(); if(si>=x+1) { if(si>=x+2) Update(1, cor[a[i]][si-(x+2)]+1, cor[a[i]][si-(x+1)]+1, -1); Update(1, cor[a[i]][si-(x+1)]+1, cor[a[i]][si-x]+1, 1); } ans += st[1].d; } printf("%lld\n", ans); } return 0; }
时间: 2024-10-25 09:14:31