经典颜色问题推荐博文 https://www.cnblogs.com/tyner/p/11519506.html https://www.cnblogs.com/tyner/p/11616770.html https://www.cnblogs.com/tyner/p/11620894.html 题意 https://www.luogu.org/problem/P4113 求一段区间中超过出现
经典颜色问题推荐博文
https://www.cnblogs.com/tyner/p/11519506.html
https://www.cnblogs.com/tyner/p/11616770.html
https://www.cnblogs.com/tyner/p/11620894.html
题意
https://www.luogu.org/problem/P4113
求一段区间中超过出现两次及以上的元素种类
分析
和其他的没啥区别,维护nxt[x], 和nxt[ nxt[x] ]即可, 还是考虑移动左端点对区间答案的影响
#include<cstdio> #include<algorithm> using namespace std; #define lowbit(x) (x&-x) const int MAX = 2000000+99; inline int read() { char ch = getchar(); int f = 1, x = 0; while(ch<'0' || ch>'9') {if(ch=='-') f = -1; ch = getchar();} while(ch>='0' && ch<='9') {x = x*10+ch-'0'; ch = getchar();} return x*f; } int n,c,m; int nxt[MAX], lst[MAX], nnxt[MAX]; int arr[MAX], t[MAX]; struct node{ int l, r, id, ans; }cmd[MAX]; bool cmp1(node a, node bb) { return a.l < bb.l;} bool cmp2(node a, node bb) { return a.id < bb.id;} void add(int x, int k) {while(x <= n) t[x] += k, x += lowbit(x);} int query(int x) { int res = 0; while(x) {res += t[x], x -= lowbit(x);} return res; } void pre() { n = read(), c = read(), m = read(); for(int i = 1; i <= n; i++) arr[i] = read(); for(int i = n; i >= 1; i--) { nxt[i] = lst[arr[i]]; lst[arr[i]] = i; } for(int i = 1; i <= n; i++) nnxt[i] = nxt[nxt[i]]; for(int i = 1; i <= c; i++) if(lst[i] && nxt[lst[i]]) add(nxt[lst[i]], 1);//颜色数为C //分清n,m for(int i = 1; i <= m; i++) cmd[i].l=read(), cmd[i].r=read(), cmd[i].id = i; sort(cmd+1, cmd+1+m, cmp1); } void solve() { int pos = 1; for(int l = 1; l <= n; l++) { while(cmd[pos].l == l) { cmd[pos].ans = query(cmd[pos].r)-query(cmd[pos].l-1); ++pos; } if(nxt[l]) add(nxt[l], -1); if(nnxt[l]) add(nnxt[l], 1); } sort(cmd+1, cmd+1+m, cmp2); for(int i = 1; i <= m; i++) printf("%d\n", cmd[i].ans); } int main() { pre(); solve(); return 0; }