注意:就算冲突了也要修改我们的num,因为这个调了一下午Σ( ° △ °|||)︴
哈希链表会好一点,因为我们要的是连续的指针,就不用映射map了。(TAT)
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #define ID bl[i] 7 #define REP(i, s, n) for(int i = s; i <= n; i ++) 8 #define RAP(i, n, s) for(int i = n; i >= s; i --) 9 using namespace std; 10 const int maxn = 100000 + 10; 11 const int maxb = 317 + 10; 12 int n, Q, w[maxb][maxb], bl[maxn], pre[maxn], suf[maxn], A[maxn], SIZE, st[maxn], en[maxn], cnt[156779][maxb]; 13 bool num[156779]; 14 int map[maxn], ms = 0; 15 const int hash_max = 156779; 16 const int hash_check = 78389; 17 const int hash_delta = 78389; 18 const int hash_find = 3901; 19 struct HASH{ 20 int hash[hash_max]; 21 bool vis[hash_max]; 22 int hash_sortn(int v){ 23 v %= hash_max; 24 if(v < 0) v += hash_max; 25 return v; 26 } 27 int hash_checkn(int v){ 28 if(v & 1) { v = v % hash_check; if(v < 0) v += hash_check; } 29 else { v = v % hash_check; if(v < 0) v += hash_check; v += hash_delta; } 30 return v; 31 } 32 int hash_findn(int v){ 33 v = (v * hash_find) % hash_max; 34 if(v < 0) v += hash_max; 35 return v; 36 } 37 int find_insert(int v){ 38 int ids = hash_sortn(v); 39 if(!vis[ids]){ 40 hash[ids] = v; 41 vis[ids] = true; 42 return map[++ ms] = ids; 43 } 44 else if(v == hash[ids]) return ids; 45 int id = hash_checkn(v); 46 if(!vis[id]){ 47 hash[id] = v; 48 vis[id] = true; 49 return map[++ ms] = id; 50 } 51 for(int i = id; ; i += hash_findn(i) + ids * i){ 52 i %= hash_max; 53 if(i < 0) i += hash_max; 54 if(!vis[i]){ 55 hash[i] = v; 56 vis[i] = true; 57 //map[++ ms] = i; 58 //return ms; 59 return map[++ ms] = i; 60 } 61 else if(v == hash[i]) return i; 62 } 63 } 64 }hashtable; 65 void read(int &x){ 66 x = 0; int sig = 1; char ch = getchar(); 67 while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); } 68 while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar(); 69 x *= sig; return ; 70 } 71 void init(){ 72 read(n); read(Q); SIZE = (int)sqrt(n); 73 bl[0] = bl[n + 1] = n + 1; 74 REP(i, 1, n){ 75 read(A[i]); 76 A[i] = hashtable.find_insert(A[i]); 77 ID = (i - 1) / SIZE + 1; 78 if(!st[ID]) st[ID] = i; 79 en[ID] = i; 80 } 81 REP(i, 1, bl[n]){ 82 int ans = 0; memset(num, false, sizeof(num)); 83 REP(j, st[i], n){ 84 if(!num[A[j]]) ans ++; 85 num[A[j]] = true; 86 w[i][bl[j]] = max(w[i][bl[j]], ans); 87 } 88 } 89 REP(i, 1, bl[n]){ 90 REP(j, 1, ms) cnt[map[j]][i] = cnt[map[j]][i - 1]; 91 REP(j, st[i], en[i]) cnt[A[j]][i] ++; 92 } 93 return ; 94 } 95 void work(){ 96 int L, R; 97 while(Q --){ 98 read(L); read(R); int ret = 0; 99 if(bl[R] - 1 < bl[L] + 1){ 100 memset(num, false, sizeof(num)); 101 REP(i, L, R){ 102 if(!num[A[i]]) ret ++; 103 num[A[i]] = true; 104 } 105 } 106 else{ 107 memset(num, false, sizeof(num)); 108 ret = w[bl[L] + 1][bl[R] - 1]; 109 REP(i, L, en[bl[L]]){ 110 if(!num[A[i]] && cnt[A[i]][bl[R] - 1] == cnt[A[i]][bl[L]]) ret ++; 111 num[A[i]] = true; 112 } 113 REP(i, st[bl[R]], R){ 114 if(!num[A[i]] && cnt[A[i]][bl[R] - 1] == cnt[A[i]][bl[L]]) ret ++; 115 num[A[i]] = true; 116 } 117 } 118 printf("%d ", ret); 119 } 120 return ; 121 } 122 void print(){ 123 124 return ; 125 } 126 int main(){ 127 init(); 128 work(); 129 print(); 130 return 0; 131 }
WZJ的哈希链表,快了300ms:
1 #include<cctype> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 using namespace std; 7 inline void read(int& x) 8 { 9 char ch=getchar();x=0; 10 while(!isdigit(ch)) ch=getchar(); 11 while(isdigit(ch)) x=x*10+ch-'0',ch=getchar(); 12 } 13 const int maxn=100010; 14 const int HASHSIZE=87153; 15 int head[HASHSIZE],next[maxn],v[maxn],tot; 16 int find(int val) 17 { 18 int k=val%HASHSIZE; 19 for(int x=head[k];x;x=next[x]) 20 if(v[x]==val) return x; 21 v[++tot]=val; 22 next[tot]=head[k]; 23 return head[k]=tot; 24 } 25 int n,m,SIZE,c[maxn],bl[maxn],st[maxn],en[maxn],cnt[10000][350],num[maxn],ans[350][350]; 26 int main() 27 { 28 read(n),read(m); SIZE=(int)sqrt(n); 29 for(int i=1;i<=n;i++) 30 { 31 read(c[i]); 32 c[i]=find(c[i]); 33 bl[i]=(i-1)/SIZE+1; 34 if(!st[bl[i]]) st[bl[i]]=i; 35 en[bl[i]]=i; 36 } 37 for(int i=1;i<=bl[n];i++) 38 { 39 int tmp=0; 40 for(int j=st[i];j<=n;j++) 41 { 42 if(++num[c[j]]==1) tmp++; 43 ans[i][bl[j]]=max(ans[i][bl[j]],tmp); 44 } 45 memset(num,0,sizeof(num)); 46 } 47 for(int i=1;i<=bl[n];i++) 48 { 49 for(int j=1;j<=tot;j++) cnt[j][i]=cnt[j][i-1]; 50 for(int j=st[i];j<=en[i];j++) cnt[c[j]][i]++; 51 } 52 int l,r,ret; 53 while(m--) 54 { 55 read(l),read(r); ret=0; 56 if(bl[l]+1>=bl[r]) 57 { 58 for(int i=l;i<=r;i++) if(++num[c[i]]==1) ret++; 59 for(int i=l;i<=r;i++) num[c[i]]=0; 60 printf("%d ",ret); 61 } 62 else 63 { 64 ret=ans[bl[l]+1][bl[r]-1]; 65 for(int i=l;i<=en[bl[l]];i++) 66 { 67 if(!num[c[i]]&&cnt[c[i]][bl[r]-1]==cnt[c[i]][bl[l]]) ret++; 68 num[c[i]]++; 69 } 70 for(int i=st[bl[r]];i<=r;i++) 71 { 72 if(!num[c[i]]&&cnt[c[i]][bl[r]-1]==cnt[c[i]][bl[l]]) ret++; 73 num[c[i]]++; 74 } 75 for(int i=l;i<=en[bl[l]];i++) num[c[i]]=0; 76 for(int i=st[bl[r]];i<=r;i++) num[c[i]]=0; 77 printf("%d ",ret); 78 } 79 } 80 return 0; 81 }