D-query SPOJ - DQUERY(模板莫队)
题意:
给定一个序列,询问m次,每次求出区间 [ L,R ] 有多少个不同数字。
套模板就好了。。。但我不大明白。。。。我的写法为什么不行。。。唉。。。
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 3001000, INF = 0x7fffffff; LL n, m, pos[maxn], s[maxn], c[maxn], ans; struct node { LL l, r, id, res; }Node[maxn]; bool cmp(node a, node b) { return pos[a.l] == pos[b.l] ? (a.r < b.r) : (a.l < b.l); } bool cmp_id(node a, node b) { return a.id < b.id; } //void update(int k, int add) //{ // if(add == 1) s[c[k]]++; // else s[c[k]]--; // if(s[c[k]] == 1) // ans++; // else if(s[c[k]] == 0) // ans--; //} void add(int x){ s[c[x]]++; if(s[c[x]]==1) ans++; } void del(int x){ s[c[x]]--; if(s[c[x]]==0) ans--; } int main() { ans = 0; scanf("%lld", &n); for(int i=1; i<=n; i++) scanf("%lld", &c[i]); int block = sqrt(n); for(int i=1; i<=n; i++) pos[i] = (i-1)/block + 1; scanf("%lld", &m); for(int i=1; i<=m; i++) { scanf("%lld%lld", &Node[i].l, &Node[i].r); Node[i].id = i; } sort(Node+1, Node+1+m, cmp); for(int i=1, l=1, r=0; i<=m; i++) { for(; r < Node[i].r; r++) add(r+1); for(; r > Node[i].r; r--) del(r); for(; l < Node[i].l; l++) del(l); for(; l > Node[i].l; l--) add(l-1); Node[i].res = ans; } sort(Node+1, Node+1+m, cmp_id); for(int i=1; i<=m; i++) printf("%I64d\n", Node[i].res); return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。