zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Ruby创始人谈Ruby的blocks和closure结构
    C语言字节对齐
    如今的开发者应了解哪些过去闻所未闻的新技能
    mongo下面总是缺少那么几个好用的工具试试这个吧MongoDB管理工具
    我们程序员为什么难晋升
    CMMI vs. Scrum vs. XP
    Rspec在Rails项目中的使用
    什么是Scrum?
    大型软件产品的敏捷案例 分享
    补充“为什么Scrum不行” (转自陈勇)
  • 原文地址:https://www.cnblogs.com/idy002/p/4364613.html
Copyright © 2011-2022 走看看