Description
给定一个长度为n的整数数组A[1]、A[2]、…、AN,和m个操作:
操作1:1 i x 把A[i]的值增加 x (-10^3<=x<=10^3);
操作2:2 x 查询整数 x 在A[1]..A[N]中出现的次数
第一行包含两个整数n和m,表示数组有n个元素,m表示有m个查询操作; 接下来的一行包含n个整数,第i个整数表示A[i]; 再接下来的m行,每行表示一个操作.
Output
按输入顺序输出操作2的结果。
1 2 3 4 5 6 7 8 9 10 11 12
| 10 9 3 5 8 17 14 21 7 6 31 5 2 9 1 2 -1 1 1 1 2 4 1 5 2 2 5 1 8 -1 1 2 1 2 5
|
Sample Output
分析
用 $Hash$ 来压缩标记数组的空间大小,选取 $Hash$ 的取余数为:$1226959$(网上搜的)
{:.success}
对于每个数 $x$,$x\mod 1226959$ 的值不容易出现重复,因此标记数组开到 $1226959$ 就行了
如果出现重复元素,用 $Vetcor$ 挂邻接表来循环查找即可
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include <bits/stdc++.h> #define haha 1226959 #define maxn 1000001 #define gethash(x) (abs(x%haha)) using namespace std; vector<int> h[haha]; vector<int> g[haha]; int a[maxn]; int n,m; inline int res(int x){ int tar=gethash(x); vector<int>::iterator iterh=h[tar].begin(); vector<int>::iterator iterg=g[tar].begin(); while(iterh!=h[tar].end()){ if(*iterh==x) return *iterg; iterh++; iterg++; } return 0; } inline void addhash(int x){ int tar=gethash(x); vector<int>::iterator iterh=h[tar].begin(); vector<int>::iterator iterg=g[tar].begin(); bool exis=false; while(iterh!=h[tar].end()){ if(*iterh==x){ exis=true; (*iterg)++; break; } iterh++; iterg++; } if(!exis){ h[tar].push_back(x); g[tar].push_back(1); } } inline void edithash(int p,int v){ int tar=gethash(p); vector<int>::iterator iterh=h[tar].begin(); vector<int>::iterator iterg=g[tar].begin(); while(iterh!=h[tar].end()){ if(*iterh==p){ (*iterg)+=v;break; } iterh++; iterg++; } } int main(){ #ifndef ONLINE_JUDGE freopen("testin.txt","r",stdin); freopen("testout.txt","w",stdout); #endif cin>>n>>m; int t,d,o; for(int i=1;i<=n;i++){ cin>>a[i]; addhash(a[i]); } while(m--){ cin>>o; if(o==1){ cin>>t>>d; edithash(a[t],-1); a[t]+=d; addhash(a[t]); }else{ cin>>t; cout<<res(t)<<'\n'; } } return 0; }
|