zoukankan      html  css  js  c++  java
  • FZU 2105 Digits Count(WA)

    裸线段树,目前WA中。

    如果用离散化的话,就跟 poj 2528 Mayor’s posters 一样中间需要插点,之前样例一直跑不对就是这个原因。

    但这个做法依然不对,我这种做法相当于默认为位运算的运算顺序不影响结果,实际上对于位运算来说,混合运算不同的运算顺序不一定得到相同的结果。

     虽然花了很长时间很大功夫也没做出来,但是知道自己错在哪里也是一种收获。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 
      6 #define lson l, m, rt << 1
      7 #define rson m + 1, r, rt << 1 | 1
      8 
      9 using namespace std;
     10 
     11 const int MAXN = 1e6;
     12 const int MAXSIZE = 222222;
     13 const int ANDFLAG = (1 << 16) - 1;
     14 
     15 struct Seg
     16 {
     17     int cnt[16];
     18     int andFlag;
     19     int orFlag;
     20     int xorFlag;
     21     bool first;
     22 };
     23 
     24 struct oper
     25 {
     26     char str[5];
     27     int a, b, val;
     28 };
     29 
     30 int N, Q;
     31 Seg ss[ MAXSIZE << 2 ];
     32 oper op[ MAXSIZE];
     33 int num[MAXN];
     34 int X[MAXSIZE << 2];
     35 
     36 void PushUp( int rt )
     37 {
     38     int lc = rt << 1;
     39     int rc = rt << 1 | 1;
     40     for ( int i = 0; i < 16; ++i )
     41         ss[rt].cnt[i] = ss[lc].cnt[i] + ss[rc].cnt[i];
     42     return;
     43 }
     44 
     45 void change( int c, int val, int *nn )
     46 {
     47     int temp[16] = { 0 };
     48 
     49     for ( int i = 0; i < 16; ++i )
     50     {
     51         int tp = i;
     52         if ( c == 1 ) tp &= val;
     53         else if ( c == 3 ) tp ^= val;
     54         else if ( c == 2 ) tp |= val;
     55      //   printf( "pre nn[%d]=%d tp=%d\n", i, nn[i], tp );
     56         temp[tp] += nn[i];
     57     }
     58 
     59     for ( int i = 0; i < 16; ++i )
     60     {
     61       //  printf("nn[%d] = %d\n", i, nn[i] );
     62         nn[i] = temp[i];
     63     }
     64 
     65     return;
     66 }
     67 
     68 void PushDown( int rt )
     69 {
     70     int lc = rt << 1;
     71     int rc = rt << 1 | 1;
     72 
     73     if ( ss[rt].andFlag != ANDFLAG )
     74     {
     75         ss[lc].andFlag = ss[rc].andFlag = ss[rt].andFlag;
     76         change( 1, ss[rt].andFlag, ss[rt].cnt );
     77         ss[rt].andFlag = ANDFLAG;
     78     }
     79 
     80     if ( ss[rt].first == false )
     81     {
     82         ss[lc].first = ss[rc].first = ss[rt].first;
     83         ss[lc].xorFlag = ss[rc].xorFlag = ss[rt].xorFlag;
     84         change( 3, ss[rt].xorFlag, ss[rt].cnt );
     85 
     86         ss[rt].first = true;
     87         ss[rt].xorFlag = 0;
     88     }
     89 
     90     if ( ss[rt].orFlag != 0 )
     91     {
     92         ss[lc].orFlag = ss[rc].orFlag = ss[rt].orFlag;
     93         change( 2, ss[rt].orFlag, ss[rt].cnt );
     94         ss[rt].orFlag = 0;
     95     }
     96 
     97     return;
     98 }
     99 
    100 int query( int L, int R, int l, int r, int rt )
    101 {
    102     if ( L <= l && r <= R )
    103     {
    104         PushDown(rt);
    105         //printf( "(%d, %d)\n", l, r );
    106         int sum = 0;
    107 
    108         //printf("query(%d, %d)\n", l, r);
    109         for ( int i = 0; i < 16; ++i )
    110         {
    111           //  printf( "%d %d\n", i, ss[rt].cnt[i] );
    112             sum += i * ss[rt].cnt[i];
    113         }
    114 
    115         return sum;
    116     }
    117 
    118     PushDown( rt );
    119     int m = ( l + r ) >> 1;
    120 
    121     int tpL = 0, tpR = 0;
    122     if ( L <= m ) tpL = query( L, R, lson );
    123     if ( R > m ) tpR = query( L, R, rson );
    124 
    125     PushUp(rt);
    126 
    127    // printf( "(%d, %d)=%d\n", l, r, tpL + tpR );
    128     return tpL + tpR;
    129 }
    130 
    131 void Update( int L, int c, int l, int r, int rt )   //插点
    132 {
    133     if ( L == l && L == r )
    134     {
    135         ++ss[rt].cnt[c];
    136         return;
    137     }
    138 
    139     int m = ( l + r ) >> 1;
    140     if ( L <= m ) Update( L, c, lson );
    141     else Update( L, c, rson );
    142 
    143     PushUp( rt );
    144     return;
    145 }
    146 
    147 void UpdateFlag( int L, int R, int c, int val, int l, int r, int rt ) //操作
    148 {
    149     if ( L <= l && r <= R )
    150     {
    151         if ( c == 1 )               //与操作
    152             ss[rt].andFlag &= val;
    153         else if ( c == 2 )          //或操作
    154             ss[rt].orFlag |= val;
    155         else                        //异或操作
    156         {
    157             if ( ss[rt].first )
    158             {
    159                 ss[rt].first = false;
    160                 ss[rt].xorFlag = val;
    161             }
    162             else ss[rt].xorFlag ^= val;
    163         }
    164         PushDown(rt);
    165 
    166        // printf( "update(%d, %d)\n", l, r );
    167         //for ( int i = 0; i < 16; ++i )
    168        // {
    169          //   printf( "%d %d\n", i, ss[rt].cnt[i] );
    170           //  sum += i * ss[rt].cnt[i];
    171         //}
    172 
    173         return;
    174     }
    175 
    176     PushDown(rt);
    177     int m = ( l + r ) >> 1;
    178     if ( L <= m ) UpdateFlag( L, R, c, val, lson );
    179     if ( R > m )  UpdateFlag( L, R, c, val, rson );
    180     PushUp(rt);
    181 
    182     return;
    183 }
    184 
    185 void build( int l, int r, int rt )   //建树初始化
    186 {
    187     memset( ss[rt].cnt, 0, sizeof(ss[rt].cnt));
    188     ss[rt].andFlag = ANDFLAG;
    189     ss[rt].orFlag = 0;
    190     ss[rt].first = true;
    191     ss[rt].xorFlag = 0;
    192 
    193     if ( l == r ) return;
    194 
    195     int m = ( l + r ) >> 1;
    196     build( lson );
    197     build( rson );
    198 
    199     return;
    200 }
    201 
    202 int BinSearch( int *nn, int tar, int x, int y )  //二分查找
    203 {
    204     int mid;
    205     while ( x < y )
    206     {
    207         mid = ( x + y ) >> 1;
    208         if ( nn[mid] == tar ) return mid;
    209         if ( nn[mid] > tar ) y = mid - 1;
    210         else x = mid + 1;
    211     }
    212     return x;
    213 }
    214 
    215 int main()
    216 {
    217     int T;
    218   //  freopen( "s.out", "w", stdout );
    219     scanf( "%d", &T );
    220     while ( T-- )
    221     {
    222         scanf( "%d%d", &N, &Q );
    223         for ( int i = 0; i < N; ++i )    //保存每个数
    224             scanf( "%d", &num[i] );
    225 
    226         int nn = 0;
    227         for ( int i = 0; i < Q; ++i )   //保存
    228         {
    229             int a, b, val;
    230             scanf( "%s", op[i].str );
    231             if ( op[i].str[0] == 'S' ) scanf( "%d%d", &a, &b );
    232             else scanf( "%d%d%d", &val, &a, &b );
    233 
    234             op[i].a = a;
    235             op[i].b = b;
    236             op[i].val = val;
    237 
    238             X[ nn++ ] = a;
    239             X[ nn++ ] = b;
    240         }
    241         sort( X, X + nn );
    242         int m = 1;
    243 
    244         for ( int i = 1; i < nn; ++i )   //去除重点
    245             if ( X[i] != X[i - 1] ) X[ m++ ] = X[i];
    246 
    247         for ( int i = m - 1; i > 0; --i )   //加点
    248             if ( X[i] != X[i - 1] + 1 )
    249                 X[m++] = X[i - 1] + 1;
    250 
    251         sort( X, X + m );
    252 /*
    253         for ( int i = 0; i < m; ++i ) printf( "%d ", X[i] );
    254         puts("");
    255 */
    256         build( 0, m, 1 );    //建树
    257         for ( int i = 0; i < N; ++i )   //插点
    258         {
    259             int addr = BinSearch( X, i, 0, m );
    260           //  printf("addr = %d\n", addr );
    261             Update( addr, num[i], 0, m, 1 );
    262         }
    263 
    264         for ( int i = 0; i < Q; ++i )
    265         {
    266             int a = BinSearch( X, op[i].a , 0, m );
    267             int b = BinSearch( X, op[i].b , 0, m );
    268 
    269             if ( op[i].str[0] == 'A' ) UpdateFlag( a, b, 1, op[i].val, 0, m, 1 );
    270             else if ( op[i].str[0] == 'O' )
    271             {
    272            //     printf("(%d, %d)\n", a, b );
    273                 UpdateFlag( a, b, 2, op[i].val, 0, m, 1 );
    274             }
    275             else if ( op[i].str[0] == 'X' ) UpdateFlag( a, b, 3, op[i].val, 0, m, 1 );
    276             else printf("%d\n", query( a, b, 0, m, 1 ) );
    277            // puts("");
    278         }
    279     }
    280     return 0;
    281 }
  • 相关阅读:
    PC-BSD 9.2 发布,基于 FreeBSD 9.2
    Attic 0.8.1 发布,备份程序
    Apache Lucene 4.5 发布,Java 搜索引擎
    Linux Kernel 3.11.4/3.10.15/3.4.65/3.0.99
    Lucene 查询工具 LQT
    Rubinius 2.0 发布,Ruby 虚拟机
    Golang通过Thrift框架完美实现跨语言调用
    微软再次要求Google审查官方链接 称将进行调查
    TCPDF 6.0.036 发布,PHP 的 PDF 操作包
    libnode 0.4.0 发布,C++ 语言版的 Node.js
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3070237.html
Copyright © 2011-2022 走看看