题意:
给一个序列,求某段区间内的不同元素个数。
解法:
1、离线 + 树状数组
将询问按照左端排序,维护元素第一次出现位置,树状数组。
const int N = 40000; int tree[N] , a[N]; int n; void add(int x){ for (; x < N ; x += low_bit(x)){ tree[x] ++; } } int query(int x){ int ret = 0; for( ; x ; x -= low_bit(x)){ ret += tree[x]; } return ret; } struct IO{ int l , r , id; void input(){ RD(l , r); } bool operator < (const IO & A) const{ return l < A.l; } }Q[200001]; int ans[200001]; typedef map<int , int> MI; MI P; MI :: iterator iter; set<int> fir; int nex[40000] , q; void solve(){ for (int i = 1 ; i <= n ; ++i) RD(a[i]); P.clear(); for(int i = n ; i ; --i){ iter = P.find(a[i]); if (iter == P.end()){ nex[i] = n + 1; } else nex[i] = iter -> se; P[a[i]] = i; }; RD(q); for (int i = 0 ; i < q ; ++i){ Q[i].input(); Q[i].id = i; } sort(Q , Q + q); RST(tree); fir.clear(); for (int i = 1 ; i <= n ; ++i){ if (fir.find(a[i]) == fir.end()){ fir.insert(a[i]); add(i); } } int head = 1 ; for (int i = 0 ; i < q ; ++i){ while(head < Q[i].l){ // cout << nex[head] << endl; if(nex[head] <= n) add(nex[head]); head++; } ans[Q[i].id] = query(Q[i].r); ans[Q[i].id] -= query(Q[i].l - 1); } for (int i = 0 ; i < q ; ++i) OT(ans[i]); } int main(){ while(~scanf("%d" , &n)) solve(); }
2、在线 + 主席树
不用离线,对于每个起始位置维护一颗主席树。每次询问在线即可
TYPE 1 :
const int N = 30009; int a[N]; MII hash; MII IT iter; int n; namespace Fotile_Tree{ const int FN = 1000009; int l[FN] /*lson*/, r[FN] , c[FN]/*Value*/ , tot; int T[FN];//T 主席树head int build(int L , int R){ int rt = ++tot ; if (L >= R) return rt; int mid = L + R >> 1; l[rt] = build(L , mid); r[rt] = build(mid + 1 , R); return rt; } int update(int rt , int p , int d){ int newrt = ++tot , root = newrt; c[newrt] = c[rt] + d ; int L = 1 , R = n; int mid; while(L < R){ mid = L + R >> 1; if (p <= mid){ l[newrt] = ++tot , r[newrt] = r[rt]; newrt = l[newrt] , rt = l[rt] , R = mid; } else{ l[newrt] = l[rt] , r[newrt] = ++tot; newrt = r[newrt] , rt = r[rt] , L = mid + 1; } c[newrt] = c[rt] + d; } return root; } int query(int rt , int p){ //Query prefix int res = 0 , L = 1 , R = n; int mid ; while(p != R){ mid = L + R >> 1; if (p <= mid){ rt = l[rt]; R = mid; } else{ res += c[l[rt]]; rt = r[rt]; L = mid + 1; } } return res + c[rt]; } } using namespace Fotile_Tree; int nex; void solve(){ for (int i = 1 ; i <= n; ++i) RD(a[i]); hash.clear(); T[n + 1] = build(1 , n); DWN_1(i , n , 1){ iter = hash.find(a[i]); if (iter == hash.end()) nex = 0; else nex = iter -> se; if (nex){ int u = update(T[i + 1] , nex , -1); T[i] = update(u , i , 1); } else T[i] = update(T[i + 1] , i , 1); hash[a[i]] = i; } Rush{ int ql , qr; RD(ql , qr); OT(query(T[ql] , qr)); } } int main(){ while(~scanf("%d" , &n)) solve(); }
TYPE 2:
const int N = 30009; int a[N]; MII hash; MII IT iter; int n; namespace Fotile_Tree{ const int FN = 1000009; int l[FN] , r[FN] , c[FN]; int T[N] , tot , _p , _c = 0; int new_node(){ return ++tot ;} void pushup(int rt) { c[rt] = c[l[rt]] + c[r[rt]]; } int node(){ int rt = new_node(); c[rt] = _c; return rt; } int node(int a , int b){ int rt = new_node(); l[rt] = a , r[rt] = b; pushup(rt); return rt; } int path(int rt , int L = 1 , int R = n){ if (L == R) return node(); int mid = L + R >> 1; if (_p <= mid) return node(path(l[rt] , L , mid) , r[rt]); else return node(l[rt] , path(r[rt] , mid + 1 , R)); } int new_path(int rt , int p , int c){ _p = p , _c = c; return path(rt); } void build(int &rt ,int L = 1 , int R = n){ rt = new_node(); if (L == R) return; int mid = L + R >> 1; build(l[rt] , L , mid); build(r[rt] , mid + 1 , R); pushup(rt); } inline int query(int rt , int p){ int res = 0 , L = 1 , R = n; while(p != R){ int mid = L + R >> 1; if (p <= mid){ rt = l[rt] , R = mid; } else{ res += c[l[rt]]; rt = r[rt] , L = mid + 1; } } return res + c[rt]; } } using namespace Fotile_Tree; int nex; void solve(){ for (int i = 1 ; i <= n; ++i) RD(a[i]); hash.clear(); build(T[n + 1] , 1 , n); DWN_1(i , n , 1){ iter = hash.find(a[i]); if (iter == hash.end()) nex = 0; else nex = iter -> se; if (nex){ int u = new_path(T[i + 1] , nex , 0); T[i] = new_path(u , i , 1); } else T[i] = new_path(T[i + 1] , i , 1); hash[a[i]] = i; } Rush{ int ql , qr; RD(ql , qr); OT(query(T[ql] , qr)); } } int main(){ while(~scanf("%d" , &n)) solve(); }
int n , Q; const int N = 1e5 + 9; int a[N]; namespace HASH{ int h[N] , m; void hashinit(){ for (int i = 1 ; i <= n ; ++i) h[i] = a[i]; h[0] = -INF; sort(h + 1 , h + n + 1); m = unique(h , h + n + 1) - h - 1; } int hashQ(int x){ return lower_bound(h , h + m + 1 , x) - h; } int number(int x){ // cout << x << endl; return h[x]; } }using namespace HASH; namespace Persistent_tree{ const int PN = 10000009; int T[N]; int l[PN] , r[PN] , c[PN] , tot; int build(int L , int R){ int rt = ++tot; if (L >= R) return rt; int mid = L + R >> 1; l[rt] = build(L , mid); r[rt] = build(mid + 1 , R); c[rt] = 0; return rt; } int update(int rt , int p , int d){ int nrt = ++tot , root = nrt; c[nrt] = c[rt] + d; int L = 1 , R = m; int mid ; while (L < R){ mid = L + R >> 1; if (p <= mid){ l[nrt] = ++tot , r[nrt] = r[rt]; nrt = l[nrt] , rt = l[rt] , R = mid; } else{ l[nrt] = l[rt] , r[nrt] = ++ tot; nrt = r[nrt] , rt = r[rt] , L = mid +1; } c[nrt] = c[rt] + d; } return root; } int query(int rtl , int rtr , int k){ int L = 1 , R = m; int mid; while(L < R){ mid = L + R >> 1; if (c[l[rtl]] - c[l[rtr]] >= k){ rtl = l[rtl]; rtr = l[rtr]; R = mid; } else{ k -= c[l[rtl]] - c[l[rtr]]; rtl = r[rtl]; rtr = r[rtr]; L = mid + 1; } // printf("[%d,%d] %d\n" , h[L] , h[R] , k); } assert(L == R); return L; } }using namespace Persistent_tree; void solve(){ for(int i = 1 ; i <= n ; ++i) RD(a[i]); hashinit(); tot = 0; T[n + 1] = build(1 , m); DWN_1(i , n , 1){ int now = hashQ(a[i]); // printf("%d = %d\n" ,a[i] , now); T[i] = update(T[i + 1] , now , 1); } DO(Q){ int L , R , k; RD(L , R , k); OT(number(query(T[L] , T[R + 1] , k))); } } int main(){ while(~scanf("%d%d" , &n , &Q)) solve(); }
岛岛的资料:
8 6 105 2 9 3 8 5 7 7 1 2 1 3 1 4 3 5 3 6 3 7 4 8 2 5 1 2 5 2 2 5 3 2 5 4 7 8 2 8 8 1 13 1 7 3 6 1 2 9 4 9 5 8 7 7 4 1 2 1 3 1 8 2 4 2 5 3 6 3 7 8 9 8 10 5 13 6 12 7 11 12 11 5Output:
2 8 9 105 7 7 9
#define LOCAL #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <vector> using namespace std; #define SZ(A) int(A.size()) #define PB push_back typedef vector<int> VI; #define REP(i, n) for (int i=0;i<int(n);++i) #define REP_1(i, n) for (int i=1;i<=int(n);++i) template<class T> inline int RD(T &x){ char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0'; return x; } /* .................................................................................................................................. */ const int N = 1e5 + 19; int a[N] , n; namespace HASH{ int h_[N] , m; void hashInit(){ for(int i = 1 ; i <= n ; ++i){ h_[i] = a[i]; } sort(h_ + 1 , h_ + n + 1); m = unique(h_ + 1 , h_ + n + 1) - h_ - 1; } int hashQ(int x){ return lower_bound(h_ + 1, h_ + m + 1 , x) - h_; } int oQ(int x){ return h_[x]; } }using namespace HASH; VI edge[N]; namespace LCA{ int pw[30]; int dep[N]; int pa[N][30] , pre[N]; void initLCA(){ for (int i = 0 ; i < 30 ; ++i) pw[i] = 1 << i; } void dfs(int u , int v , int deep){ dep[u] = deep; pre[u] = v; for(int i = 0 ; i < SZ(edge[u]) ; ++i){ int go = edge[u][i]; if (go == v) continue; dfs(go , u , deep + 1); } } void make_parent(){ memset(pa , -1 , sizeof(pa)); REP_1(i , n) pa[i][0] = pre[i]; for (int j = 1 ; pw[j] < n ; j++) REP_1(i , n) if (pa[i][j - 1] != -1) pa[i][j] = pa[pa[i][j - 1]][j - 1]; } int lca(int x , int y){ int i , log = 0; if (dep[x] < dep[y]) swap(x , y); while(pw[log + 1] <= dep[x]) log++; for (i = log ; i >= 0 ; --i) if (dep[x] - pw[i] >= dep[y]) x = pa[x][i]; if (x == y) return x; for (i = log ; i >= 0 ; i--) if (pa[x][i] != -1 && pa[x][i] != pa[y][i]) x = pa[x][i] , y = pa[y][i]; return pre[x]; } }using namespace LCA; namespace Persistent_tree{ const int TN = N * 23; int T[N]; int l[TN] , r[TN] , c[TN] , tot; int build(int L , int R){ int rt = ++ tot; if (L >= R) return rt; int mid = L + R >> 1; l[rt] = build(L , mid); r[rt] = build(mid + 1 , R); c[rt] = 0; return rt; } int update(int rt , int p , int d){ int nrt = ++tot , root = nrt; c[nrt] = c[rt] + d; int L = 1 , R = m; int mid ; while (L < R){ mid = L + R >> 1; if (p <= mid){ l[nrt] = ++ tot , r[nrt] = r[rt]; nrt = l[nrt] , rt = l[rt] , R = mid; } else{ l[nrt] = l[rt] , r[nrt] = ++tot; nrt = r[nrt] , rt = r[rt] , L = mid + 1; } c[nrt] = c[rt] + d; } return root; } int query(int x , int y , int z , int k){ int L = 1 , R = m; int mid; int rtx = T[x] , rty = T[y] , rtlca = T[z]; int now = a[z] , t; while(L < R){ mid = L + R >> 1; // printf("C %d %d %d\n" , c[l[rtx]] , c[l[rty]] , c[l[rtlca]]); if ((t = c[l[rtx]] + c[l[rty]] - 2 * c[l[rtlca]] + (L <= now && now <= mid) )>= k){ rtx = l[rtx]; rty = l[rty]; rtlca = l[rtlca]; R = mid; } else{ k -= t; rtx = r[rtx]; rty = r[rty]; rtlca = r[rtlca]; L = mid + 1; } // printf("%d %d - [%d %d] %d\n" , L , R , oQ(L) , oQ(R) , k); } return L; } }using namespace Persistent_tree; void buildtree(int u , int v){ // printf("a[%d] = %d\n" , u , a[u]); T[u] = update(T[v] , a[u] , 1); REP(i , SZ(edge[u])){ int go = edge[u][i]; if (go == v) continue; buildtree(go , u); } } int Q; void solve(){ REP_1(i , n){ edge[i].clear(); RD(a[i]); } hashInit(); REP_1(i , n) a[i] = hashQ(a[i]); REP_1(i , n - 1){ int x , y; RD(x) ; RD(y); edge[x].PB(y); edge[y].PB(x); } initLCA(); dfs(1 , 1 , 0); make_parent(); tot = 0; T[0] = build(1 , m); buildtree(1 , 0); while(Q--){ int L , R , k , rt; RD(L) , RD(R) , RD(k); rt = lca(L , R); // if (L == R) printf("%d\n" , oQ(a[L])); // printf("%d %d %d\n" , L , R , rt); printf("%d\n" , oQ(query(L , R , rt , k))); } } int main(){ // freopen("COT.txt" , "r" , stdin); while(~scanf("%d%d" , &n , &Q)) solve(); }
int n , k; const int N = 5e4 + 5; const int hashN = 6e4 + 5; int a[N]; //namespace HASH{ int h_[hashN] , m; void hashInitpre(){ for(int i = 1 ; i <= n ; ++i){ h_[i] = a[i]; } m = n; } void hashInitfinal(){ sort(h_ + 1 , h_ + m + 1); m = unique(h_ + 1 , h_ + m + 1) - h_ - 1; } int hashQ(int x){ return lower_bound(h_ + 1, h_ + m + 1 , x) - h_; } int oQ(int x){ return h_[x]; } //}using namespace HASH; //namespace Persistent_Tree{ const int TN = 2705005; int T[N]; int l[TN] , r[TN] ; short c[TN]; int tot; int build(int L , int R){ int rt = ++ tot; if (L >= R) return rt; int mid = L + R >> 1; l[rt] = build(L , mid); r[rt] = build(mid + 1 , R); c[rt] = 0; return rt; } int update(int rt , int p , int d){ int nrt = ++tot , root = nrt; c[nrt] = c[rt] + d; int L = 1 , R = m; int mid; while(L < R){ mid = L + R >> 1; if (p <= mid){ l[nrt] = ++tot , r[nrt] = r[rt]; nrt = l[nrt] , rt = l[rt] , R = mid; } else{ l[nrt] = l[rt] , r[nrt] = ++tot; nrt = r[nrt] , rt= r[rt] , L = mid + 1; } c[nrt] = c[rt] + d; } return root; } //}using namespace Persistent_Tree; //namespace BIT{ int bit[hashN]; void BITinit(int rt , int tn){ tot = 0; T[rt] = build(1 , tn); for (int i = 1 ; i <= tn ; ++i) T[i] = T[rt]; } void add(int x , int pos , int c){ for ( ; x <= m ; x += low_bit(x)) T[x] = update(T[x] , pos , c); } int sum(int x){ int ret = 0; for( ; x ; x -= low_bit(x)) ret += c[l[bit[x]]]; return ret; } int query(int ql , int qr , int k){ for (int i = ql ; i ; i -= low_bit(i)) bit[i] = T[i]; for (int i = qr ; i ; i -= low_bit(i)) bit[i] = T[i]; int L = 1 , R = m; int mid; int t; while(L < R){ mid = L + R >> 1; t = sum(qr) - sum(ql); if (t >= k){ for (int i = ql ; i ; i -= low_bit(i)) bit[i] = l[bit[i]]; for (int i = qr ; i ; i -= low_bit(i)) bit[i] = l[bit[i]]; R = mid; } else{ k -= t; for (int i = ql ; i ; i -= low_bit(i)) bit[i] = r[bit[i]]; for (int i = qr ; i ; i -= low_bit(i)) bit[i] = r[bit[i]]; L = mid + 1; } // printf("[%2d , %2d] %d\n" , oQ(L) , oQ(R) , k); } return L; } //}using namespace BIT; char op[2]; int Q; const int QN = 1e4 + 5; struct IO{ bool change; int x , y , k; void input(){ RS(op); if(op[0] == 'C'){ change = 1; RD(x , y); h_[ ++m ] = y; } else{ change = 0; RD(x , y , k); } } }q[QN]; const int BZOJ = 0; void solve(){ if(!BZOJ)RD(n , Q); REP_1(i , n) RD(a[i]); hashInitpre(); REP(i , Q) q[i].input(); hashInitfinal(); REP_1(i , n) a[i] = hashQ(a[i]); REP(i , Q) if (q[i].change) q[i].y = hashQ(q[i].y); BITinit(0 , m); REP_1(i , n) add(i , a[i] , 1); REP(qq , Q){ if (q[qq].change){ int pos = q[qq].x; add(pos , a[pos] , -1); add(pos , q[qq].y , 1); a[pos] = q[qq].y; } else{ OT(oQ(query(q[qq].x - 1 , q[qq].y , q[qq].k))); } } } int main(){ if (BZOJ)while(~scanf("%d%d" , &n , &Q)) solve(); else{ Rush solve(); } }
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3767
http://user.qzone.qq.com/251815992/blog/1346399378
资料:http://www.shuizilong.com/house/archives/uva-12345-dynamic-lensetalr/
sad...终于搞掉了。。小岛写的还是很NB的。。
题意:
对于一个长度为N (<= 5e4) 的序列,支持一下两种操作:
1、修改某个值
2、求区间第k大
解法:
树状数组 套 主席树 1.084s
这题对树状数组分割区间的理解有很大的帮助啊!!!
还有不要瞎Hash 啊,Hash 一下我就超时了T_T
方法是用个Set记录每个数的pre , 插入主席树中。。这题相当Nice需要继续参透
#define LOCAL /** ` Micro Mezzo Macro Flation -- Overheated Economy ., Ver 0.1 **/ #include <functional> #include <algorithm> #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cstring> #include <cassert> #include <cstdio> #include <string> #include <vector> #include <bitset> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <list> #include <set> #include <map> using namespace std; #define REP(i, n__) for (int i=0;i<int(n__);++i) #define FOR(i, a, b) for (int i=int(a);i<int(b);++i) #define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i) #define REP_1(i, n__) for (int i=1;i<=int(n__);++i) #define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i) #define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i) #define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i) #define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i) #define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i) #define REP_N(i, n) for (i=0;i<int(n);++i) #define FOR_N(i, a, b) for (i=int(a);i<int(b);++i) #define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i) #define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i) #define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i) #define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i) #define REP_1_N(i, n) for (i=1;i<=int(n);++i) #define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i) #define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i) #define REP_C_N(i, n) for (n____=int(n),i=0;i<n____;++i) #define FOR_C_N(i, a, b) for (b____=int(b),i=a;i<b____;++i) #define DWN_C_N(i, b, a) for (a____=int(a),i=b-1;i>=a____;--i) #define REP_1_C_N(i, n) for (n____=int(n),i=1;i<=n____;++i) #define FOR_1_C_N(i, a, b) for (b____=int(b),i=a;i<=b____;++i) #define DWN_1_C_N(i, b, a) for (a____=int(a),i=b;i>=a____;--i) //#define ECH(it, A) for (typeof(A.begin()) it=A.begin(); it != A.end(); ++it) #define ECH(it, A) for (__typeof(A.begin()) it=A.begin(); it != A.end(); ++it) #define REP_S(it, str) for (char*it=str;*it;++it) #define REP_G(it, u) for (int it=hd[u];it;it=suc[it]) #define DO(n) for ( int ____n ## __line__ = n; ____n ## __line__ -- ; ) #define REP_2(i, j, n, m) REP(i, n) REP(j, m) #define REP_2_1(i, j, n, m) REP_1(i, n) REP_1(j, m) #define REP_3(i, j, k, n, m, l) REP(i, n) REP(j, m) REP(k, l) #define REP_3_1(i, j, k, n, m, l) REP_1(i, n) REP_1(j, m) REP_1(k, l) #define ALL(A) A.begin(), A.end() #define LLA(A) A.rbegin(), A.rend() #define CPY(A, B) memcpy(A, B, sizeof(A)) #define INS(A, P, B) A.insert(A.begin() + P, B) #define ERS(A, P) A.erase(A.begin() + P) #define BSC(A, X) find(ALL(A), X) // != A.end() #define CTN(T, x) (T.find(x) != T.end()) #define SZ(A) int(A.size()) #define PB push_back #define MP(A, B) make_pair(A, B) #define PTT pair<T, T> #define fi first #define se second #define Rush for(int ____T=RD(); ____T--;) #define Display(A, n, m) { \ REP(i, n){ \ REP(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \ } #define Display_1(A, n, m) { \ REP_1(i, n){ \ REP_1(j, m) cout << A[i][j] << " "; \ cout << endl; \ } \ } #pragma comment(linker, "/STACK:36777216") //#pragma GCC optimize ("O2") #define Ruby system("ruby main.rb") #define Haskell system("runghc main.hs") #define Python system("python main.py") #define Pascal system("fpc main.pas") typedef long long LL; //typedef long double DB; typedef double DB; typedef unsigned UINT; typedef unsigned long long ULL; typedef vector<int> VI; typedef vector<char> VC; typedef vector<string> VS; typedef vector<LL> VL; typedef vector<DB> VD; typedef set<int> SI; typedef set<string> SS; typedef set<LL> SL; typedef set<DB> SD; typedef map<int, int> MII; typedef map<string, int> MSI; typedef map<LL, int> MLI; typedef map<DB, int> MDI; typedef pair<int, int> PII; typedef pair<int, bool> PIB; typedef pair<LL, LL> PLL; typedef vector<PII> VII; typedef vector<VI> VVI; typedef vector<VII> VVII; template<class T> inline T& RD(T &); template<class T> inline void OT(const T &); inline LL RD(){LL x; return RD(x);} inline char& RC(char &c){scanf(" %c", &c); return c;} inline char RC(){char c; return RC(c);} //inline char& RC(char &c){c = getchar(); return c;} //inline char RC(){return getchar();} inline DB& RF(DB &x){scanf("%lf", &x); return x;} inline DB RF(){DB x; return RF(x);} inline char* RS(char *s){scanf("%s", s); return s;} template<class T0, class T1> inline T0& RD(T0 &x0, T1 &x1){RD(x0), RD(x1); return x0;} template<class T0, class T1, class T2> inline T0& RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2); return x0;} template<class T0, class T1, class T2, class T3> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3); return x0;} template<class T0, class T1, class T2, class T3, class T4> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4); return x0;} template<class T0, class T1, class T2, class T3, class T4, class T5> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5); return x0;} template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6); return x0;} template<class T0, class T1> inline void OT(const T0 &x0, const T1 &x1){OT(x0), OT(x1);} template<class T0, class T1, class T2> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2){OT(x0), OT(x1), OT(x2);} template<class T0, class T1, class T2, class T3> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);} template<class T0, class T1, class T2, class T3, class T4> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);} template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);} template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5, const T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);} inline char& RC(char &a, char &b){RC(a), RC(b); return a;} inline char& RC(char &a, char &b, char &c){RC(a), RC(b), RC(c); return a;} inline char& RC(char &a, char &b, char &c, char &d){RC(a), RC(b), RC(c), RC(d); return a;} inline char& RC(char &a, char &b, char &c, char &d, char &e){RC(a), RC(b), RC(c), RC(d), RC(e); return a;} inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f){RC(a), RC(b), RC(c), RC(d), RC(e), RC(f); return a;} inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f, char &g){RC(a), RC(b), RC(c), RC(d), RC(e), RC(f), RC(g); return a;} inline DB& RF(DB &a, DB &b){RF(a), RF(b); return a;} inline DB& RF(DB &a, DB &b, DB &c){RF(a), RF(b), RF(c); return a;} inline DB& RF(DB &a, DB &b, DB &c, DB &d){RF(a), RF(b), RF(c), RF(d); return a;} inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e){RF(a), RF(b), RF(c), RF(d), RF(e); return a;} inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f){RF(a), RF(b), RF(c), RF(d), RF(e), RF(f); return a;} inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f, DB &g){RF(a), RF(b), RF(c), RF(d), RF(e), RF(f), RF(g); return a;} inline void RS(char *s1, char *s2){RS(s1), RS(s2);} inline void RS(char *s1, char *s2, char *s3){RS(s1), RS(s2), RS(s3);} template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));} template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);} template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);} template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);} template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);} template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);} template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);} template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));} template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);} template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x);} template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x);} template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x);} template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x);} template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x), FLC(A6, x);} template<class T> inline void CLR(priority_queue<T, vector<T>, less<T> > &Q){while (!Q.empty()) Q.pop();} template<class T> inline void CLR(priority_queue<T, vector<T>, greater<T> > &Q){while (!Q.empty()) Q.pop();} template<class T> inline void CLR(T &A){A.clear();} template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);} template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);} template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);} template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);} template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);} template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);} template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);} template<class T> inline T& SRT(T &A){sort(ALL(A)); return A;} template<class T, class C> inline T& SRT(T &A, C B){sort(ALL(A), B); return A;} // <<= ` 0. Daily Use ., template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;} template<class T> inline void checkMax(T &a,const T b){if (a<b) a=b;} template<class T> inline void checkMin(T &a, T &b, const T x){checkMin(a, x), checkMin(b, x);} template<class T> inline void checkMax(T &a, T &b, const T x){checkMax(a, x), checkMax(b, x);} template <class T, class C> inline void checkMin(T& a, const T b, C c){if (c(b,a)) a = b;} template <class T, class C> inline void checkMax(T& a, const T b, C c){if (c(a,b)) a = b;} template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);} template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);} template<class T> inline T min(T a, T b, T c, T d){return min(min(a, b), min(c, d));} template<class T> inline T max(T a, T b, T c, T d){return max(max(a, b), max(c, d));} template<class T> inline T sqr(T a){return a*a;} template<class T> inline T cub(T a){return a*a*a;} inline int Ceil(int x, int y){return (x - 1) / y + 1;} // <<= ` 1. Bitwise Operation ., namespace BO{ inline bool _1(int x, int i){return bool(x&1<<i);} inline bool _1(LL x, int i){return bool(x&1LL<<i);} inline LL _1(int i){return 1LL<<i;} inline LL _U(int i){return _1(i) - 1;}; inline int reverse_bits(int x){ x = ((x >> 1) & 0x55555555) | ((x << 1) & 0xaaaaaaaa); x = ((x >> 2) & 0x33333333) | ((x << 2) & 0xcccccccc); x = ((x >> 4) & 0x0f0f0f0f) | ((x << 4) & 0xf0f0f0f0); x = ((x >> 8) & 0x00ff00ff) | ((x << 8) & 0xff00ff00); x = ((x >>16) & 0x0000ffff) | ((x <<16) & 0xffff0000); return x; } inline LL reverse_bits(LL x){ x = ((x >> 1) & 0x5555555555555555LL) | ((x << 1) & 0xaaaaaaaaaaaaaaaaLL); x = ((x >> 2) & 0x3333333333333333LL) | ((x << 2) & 0xccccccccccccccccLL); x = ((x >> 4) & 0x0f0f0f0f0f0f0f0fLL) | ((x << 4) & 0xf0f0f0f0f0f0f0f0LL); x = ((x >> 8) & 0x00ff00ff00ff00ffLL) | ((x << 8) & 0xff00ff00ff00ff00LL); x = ((x >>16) & 0x0000ffff0000ffffLL) | ((x <<16) & 0xffff0000ffff0000LL); x = ((x >>32) & 0x00000000ffffffffLL) | ((x <<32) & 0xffffffff00000000LL); return x; } template<class T> inline bool odd(T x){return x&1;} template<class T> inline T low_bit(T x) {return x & -x;} template<class T> inline T high_bit(T x) {T p = low_bit(x);while (p != x) x -= p, p = low_bit(x);return p;} template<class T> inline T cover_bit(T x){T p = 1; while (p < x) p <<= 1;return p;} inline int low_idx(int x){return __builtin_ffs(x);} inline int low_idx(LL x){return __builtin_ffsll(x);} inline int high_idx(int x){return low_idx(reverse_bits(x));} inline int high_idx(LL x){return low_idx(reverse_bits(x));} inline int clz(int x){return __builtin_clz(x);} inline int clz(LL x){return __builtin_clzll(x);} inline int ctz(int x){return __builtin_ctz(x);} inline int ctz(LL x){return __builtin_ctzll(x);} inline int parity(int x){return __builtin_parity(x);} inline int parity(LL x){return __builtin_parityll(x);} inline int lg2(int a){return 31 - __builtin_clz(a);} inline int count_bits(int x){return __builtin_popcount(x);} inline int count_bits(LL x){return __builtin_popcountll(x);} } using namespace BO; template<class T> inline T& RD(T &x){ //cin >> x; // scanf("%d", &x); char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); '0' <= c && c <= '9'; c = getchar()) x = x * 10 + c - '0'; //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0'; return x; } int ____Case; template<class T> inline void OT(const T &x){ //if (x == -1) printf("Case %d: NO\n", ++____Case); //else printf("Case %d: %d\n", ++____Case, x); //printf("%I64d\n", x); //printf("%.2lf\n", x); printf("%d\n", x); // cout << x << endl; } /* .................................................................................................................................. */ const int N = 5e4 + 19; int a[N] , n , Q; const int M = 1e6 + 9; int qx , qy; namespace Persistent_tree{ const int TN = N * 60 * 50; int T[N]; int l[TN] , r[TN] , c[TN] , tot , pre[N]; int build(int L , int R){ int rt = ++ tot; if (L >= R) return rt; int mid = L + R >> 1; l[rt] = build(L , mid); r[rt] = build(mid + 1 , R); c[rt] = 0; return rt; } int update(int rt , int p , int d){ int nrt = ++tot , root = nrt; c[nrt] = c[rt] + d; int L = 0 , R = n; int mid ; while (L < R){ mid = L + R >> 1; if (p <= mid){ l[nrt] = ++ tot , r[nrt] = r[rt]; nrt = l[nrt] , rt = l[rt] , R = mid; } else{ l[nrt] = l[rt] , r[nrt] = ++tot; nrt = r[nrt] , rt = r[rt] , L = mid + 1; } c[nrt] = c[rt] + d; } return root; } int query(int rt){ //Query prefix int res = 0 , L = 0 , R = n; int mid ; while(L < R){ mid = L + R >> 1; if (qx <= mid){ rt = l[rt]; R = mid; } else{ res += c[l[rt]]; rt = r[rt]; L = mid + 1; } } return res;// + c[rt]; } }; #define PT Persistent_tree namespace BIT{ void Modify(int rt , int &x , int y){ for ( ; rt <= n ; rt += low_bit(rt)){ PT::T[rt] = PT::update(PT::T[rt] , x , -1) ; PT::T[rt] = PT::update(PT::T[rt] , y , 1); } x = y; } int lsum(int rt){ int ret = PT::query(PT::pre[rt]); for( ; rt ; rt ^= low_bit(rt)) ret += PT::query(PT::T[rt]); return ret; } int query(int l, int r){ return lsum(r) - lsum(l - 1); } }; int Pre[N]; SI H[M]; SI :: iterator iter; int main(){ //freopen("0.txt" , "r" , stdin); RD(n , Q); PT::tot = 0; #define BT BIT REP_1(i , n) RD(a[i]); int Null = PT::build(0 , n); REP_1(i , n) PT::T[i] = Null; REP_1(i , n){ iter = H[a[i]].lower_bound(i); if(iter != H[a[i]].begin())Pre[i] = *--iter; H[a[i]].insert(i); } PT::pre[0] = Null; REP_1(i , n) PT::pre[i] = PT::update(PT::pre[i - 1] , Pre[i] , 1); char op; DO(Q){ RC(op); qx = RD() + 1; qy = RD(); if (op == 'M'){ if (a[qx] == qy) continue; SI &sx = H[a[qx]] , &sy = H[qy]; sx.erase(qx); iter = sx.lower_bound(qx); if(iter != sx.end()) BT::Modify(*iter , Pre[*iter] , Pre[qx]); iter = sy.lower_bound(qx); if (iter == sy.begin()) BT::Modify(qx , Pre[qx] , 0); else BT::Modify(qx , Pre[qx] , *--sy.lower_bound(qx)); if (iter != sy.end()) BT::Modify(*iter , Pre[*iter] , qx); sy.insert(qx); a[qx] = qy; } else OT(BT::query(qx , qy)); } }
http://www.acdream.net/problem.php?cid=1011&pid=2
资料:http://www.shuizilong.com/house/archives/%E3%80%90%E7%AC%AC%E5%9B%9B%E6%AC%A1-acdream-%E7%BE%A4%E5%8E%9F%E5%88%9B%E7%BE%A4%E8%B5%9B%E3%80%91%E8%A7%A3%E9%A2%98%E6%8A%A5%E5%91%8A/
资料:http://www.shuizilong.com/house/archives/codeforces-round-140/
/* Time 的优化: 每次update的时候更新每个节点的UPD,如果下次更新的时候发现 UPD = Time 也就是这个节点属于本子树,那么直接更新否则加点。 */ const int N = 1e5 + 1009; int Time; struct Node{ Node * lson , *rson; LL add , sum; int l , r; int UPD; Node(){} Node(int updtime = Time){ add = 0 , sum = 0; lson = NULL ; rson = NULL; UPD = updtime; } void pushup(){ sum = 0; if (lson) sum += lson -> sum; if (rson) sum += rson -> sum; } void pushdown(int updtime); void copy(Node * pre){ lson = pre -> lson; rson = pre -> rson; l = pre -> l; r = pre -> r; } }*C , *T[N]; int cnt; Node * newNode(int updtime = Time){ C = new Node(updtime); return C; } void Node::pushdown(int updtime){ if (lson && lson -> UPD != updtime){ Node * newlson = newNode(updtime); newlson -> sum = lson -> sum; newlson -> add = lson -> add; newlson -> copy(lson); lson = newlson; } if (rson && rson -> UPD != updtime){ Node * newrson = newNode(updtime); newrson -> sum = rson -> sum; newrson -> add = rson -> add; newrson -> copy(rson); rson = newrson; } if (add == 0) return; int mid = l + r >> 1; if (lson){ lson -> sum = lson -> sum + add * (mid - l + 1); lson -> add = lson -> add + add; } if (rson){ rson -> sum = rson -> sum + add * (r - mid); rson -> add = rson -> add + add; } add = 0; } void build(Node *& rt , int l , int r){ rt = newNode(); rt -> l = l , rt -> r = r; if (l == r){ cin >> rt -> sum; return; } int m = l + r >> 1; if (l <= m) build(rt -> lson , l , m); if (m < r) build(rt -> rson , m + 1 , r); rt -> pushup(); } void update(Node * pre , Node *&rt , int L , int R , int l , int r , LL c , int _time = Time){ if (rt == NULL || rt -> UPD != _time){ rt = newNode(_time); rt -> add = pre -> add; rt -> sum = pre -> sum; rt -> copy(pre); } if (L <= l && r <= R){ rt -> add += c; rt -> sum += c * (r - l + 1); return; } rt -> pushdown(_time); int m = l + r >> 1; if (L <= m) update(pre -> lson , rt -> lson , L , R , l , m , c , _time); if (m < R) update(pre -> rson , rt -> rson , L , R , m + 1 , r , c , _time); rt -> pushup(); } LL query(Node * rt , int L , int R , int l , int r , int _time = Time){ if (L <= l && r <= R) return rt -> sum; rt -> pushdown(_time); int m = l + r >> 1; LL res = 0; if (L <= m) res += query(rt -> lson , L , R , l , m , _time); if (m < R) res += query(rt -> rson , L , R , m + 1 , r , _time); rt -> pushup(); return res; } int n , m; char op[15]; int l , r , t; LL d; void work(){ cin >> op; if (op[0] == 'C'){ T[Time + 1] = NULL; cin >> l >> r >> d; update(T[Time] , T[Time + 1] , l , r , 1 , n , d , Time + 1); Time++; } else if (op[0] == 'Q'){ cin >> l >> r; cout << query(T[Time] , l , r , 1 , n , Time) << endl; } else if (op[0] == 'H'){ cin >> l >> r >> t; cout << query(T[t] , l , r , 1 , n , t) << endl; } else{ cin >> Time; } } void solve(){ T[0] = NULL; C = NULL; cnt = 0; Time = 0; build(T[0] , 1 , n); DO(m) work(); } int main(){ ios::sync_with_stdio(false); while(cin >> n >> m) solve(); }