bzoj 2120

先将问题转化为带修改的求区间小于某数的数的数量,然后用树状数组套值域线段树解决。

注意:

  1、值域线段树要包括0

  1 /**************************************************************
  2     Problem: 2120
  3     User: idy002
  4     Language: C++
  5     Result: Accepted
  6     Time:1556 ms
  7     Memory:35512 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <set>
 12 #define maxs 600000
 13 #define maxn 10010
 14 #define maxa 1000000
 15 using namespace std;
 16  
 17 struct Node {
 18     int sz;
 19     Node *ls, *rs;
 20 }pool[maxs], *tail=pool, *root[maxn], *nds[maxn]; int ndc;
 21  
 22 int n, m;
 23 int aa[maxn], vv[maxa+1];
 24 int prv[maxn], nxt[maxn];
 25 set<int> st[maxa+1];
 26  
 27 Node *newnode() {
 28     Node *nd = ++tail;
 29     nd->sz = 0;
 30     nd->ls = nd->rs = 0;
 31     return nd;
 32 }
 33 void mdf_sgt( Node *nd, int lf, int rg, int pos, int delta ) {
 34     if( lf==rg ) {
 35         nd->sz += delta;
 36         return;
 37     }
 38     int mid=(lf+rg)>>1;
 39     if( pos<=mid ) {
 40         if( !nd->ls ) nd->ls = newnode();
 41         mdf_sgt( nd->ls, lf, mid, pos, delta );
 42     } else {
 43         if( !nd->rs ) nd->rs = newnode();
 44         mdf_sgt( nd->rs, mid+1, rg, pos, delta );
 45     }
 46     nd->sz = 0;
 47     if( nd->ls ) nd->sz+=nd->ls->sz;
 48     if( nd->rs ) nd->sz+=nd->rs->sz;
 49 }
 50 int qry_sgt( int lf, int rg, int top ) {
 51     if( lf==rg ) {
 52         int rt=0;
 53         for( int i=1; i<=ndc; i++ )
 54             if( nds[i] )
 55                 rt += nds[i]->sz;
 56         return rt;
 57     }
 58     int mid=(lf+rg)>>1;
 59     if( top<=mid+1 ) {
 60         for( int i=1; i<=ndc; i++ )
 61             if( nds[i] )
 62                 nds[i] = nds[i]->ls;
 63         return qry_sgt(lf,mid,top);
 64     } else {
 65         int rt = 0;
 66         for( int i=1; i<=ndc; i++ )
 67             if( nds[i] ) {
 68                 if( nds[i]->ls )
 69                     rt += nds[i]->ls->sz;
 70                 nds[i] = nds[i]->rs;
 71             }
 72         rt += qry_sgt(mid+1,rg,top);
 73         return rt;
 74     }
 75 }
 76 void init() {
 77     for( int i=1; i<=n; i++ ) {
 78         scanf( "%d", aa+i );
 79         if( vv[aa[i]] ) {
 80             prv[i] = vv[aa[i]];
 81             nxt[prv[i]] = i;
 82         }
 83         vv[aa[i]] = i;
 84         st[aa[i]].insert(i);
 85     }
 86  
 87     for( int i=1; i<=n; i++ )
 88         root[i] = newnode();
 89     for( int i=1; i<=n; i++ )
 90         for( int j=i; j<=n; j+=j&-j )
 91             mdf_sgt( root[j], 0, maxa, prv[i], +1 );
 92 }
 93 void mdf_sub( int pos, int oldv, int newv ) {
 94     for( int i=pos; i<=n; i+=i&-i )
 95         mdf_sgt( root[i], 0, maxa, oldv, -1 );
 96     for( int i=pos; i<=n; i+=i&-i )
 97         mdf_sgt( root[i], 0, maxa, newv, +1 );
 98 }
 99 void modify( int pos, int val ) {
100     int a=prv[pos], b=nxt[pos];
101     int p=0, q=0;
102  
103     st[aa[pos]].erase(pos);
104     set<int>::iterator it = st[val].insert( pos ).first;
105     aa[pos] = val;
106  
107     if( it!=st[val].begin() ) {
108         --it;
109         p = *it;
110         ++it;
111     }
112     ++it;
113     if( it!=st[val].end() )
114         q = *it;
115  
116     prv[pos] = p;
117     nxt[pos] = q;
118     if( b ) prv[b] = a;
119     if( a ) nxt[a] = b;
120     if( p ) nxt[p] = pos;
121     if( q ) prv[q] = pos;
122     mdf_sub( pos, a, p );
123     if( b ) mdf_sub( b, pos, a );
124     if( q ) mdf_sub( q, p, pos );
125 }
126 int qry_sub( int R, int top ) {
127     ndc = 0;
128     for( int i=R; i; i-=i&-i )
129         nds[++ndc]=root[i];
130     int rt = qry_sgt(0,maxa,top);
131     return rt;
132 }
133 int query( int L, int R ) {
134     return qry_sub(R,L)-(L==1?0:qry_sub(L-1,L));
135 }
136 int main() {
137     scanf( "%d%d", &n, &m );
138     init();
139     for( int i=1; i<=m; i++ ) {
140         char ch[10];
141         scanf( "%s", ch );
142         if( ch[0]=='R' ) {
143             int p, c;
144             scanf( "%d%d", &p, &c );
145             modify( p, c );
146         } else {
147             int l, r;
148             scanf( "%d%d", &l, &r );
149             printf( "%d
", query(l,r) );
150         }
151     }
152 }
View Code
原文地址:https://www.cnblogs.com/idy002/p/4364613.html