题目大意:给出一个序列,问一段序列中,出现两次以上的颜色有多少种。
思路:和HH的项链很像。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1000010 using namespace std; struct Ask{ int x,y,_id; bool operator <(const Ask &a)const { return x < a.x; } void Read(int p) { scanf("%d%d",&x,&y); _id = p; } }ask[MAX]; int cnt,cols,asks; int fenwick[MAX]; int src[MAX]; int last[MAX],next[MAX]; int T[MAX]; int ans[MAX]; inline void Fix(int x,int c) { if(!x) return ; for(; x <= cnt; x += x&-x) fenwick[x] += c; } inline int GetSum(int x) { int re = 0; for(; x; x -= x&-x) re += fenwick[x]; return re; } int main() { cin >> cnt >> cols >> asks; for(int i = 1; i <= cnt; ++i) scanf("%d",&src[i]); for(int i = 1; i <= cnt; ++i) { if(++T[src[i]] == 2) Fix(i,1); if(last[src[i]]) next[last[src[i]]] = i; last[src[i]] = i; } for(int i = 1;i <= asks; ++i) ask[i].Read(i); sort(ask + 1,ask + asks + 1); ask[0].x = 1; for(int i = 1; i <= asks; ++i) { for(int j = ask[i - 1].x; j < ask[i].x; ++j) { Fix(next[j],-1); Fix(next[next[j]],1); } ans[ask[i]._id] = GetSum(ask[i].y); } for(int i = 1; i <= asks; ++i) printf("%d\n",ans[i]); return 0; }
时间: 2024-10-09 18:51:59