• AtCoder ABC 157E Simple String Queries


    题目链接:https://atcoder.jp/contests/abc157/tasks/abc157_e

    题目大意

      给定一串全由小写英文字母组成的字符串,然后顺序给出$Q$个操作,一种为替换字符串中的某个字符;另一种为查询字符串某个区间里面有多少个不同的字符。要求顺序输出第二种操作的结果。

    分析

      线段树单点更新,每个节点存一个32位整数,其中26位代表26个英文字母,更新的话只要节点求或就行了。
      其他方法1:用26个树状数组,这个原理是一样的,但总感觉没有只用一棵线段树简明。
      其他方法2:把每个字母出现的位置存到有序表里面,然后查询的时候利用二分看看字母在不在区间里面,在的话就加一。
      以上方法时间复杂度都为$O(QlogN)$,我选用的是一棵线段树的做法。

    代码如下

      1 #pragma GCC optimize(2)
      2 #include <bits/stdc++.h>
      3 using namespace std;
      4 
      5 /*-------------------Define Start-------------------*/
      6 typedef bool BL;                        // 布尔类型
      7 typedef char SB;                        // 有符号1字节,8位
      8 typedef unsigned char UB;                // 无符号1字节,8位
      9 typedef short SW;                        // 有符号短整型,16位
     10 typedef unsigned short UW;                // 无符号短整型,16位
     11 typedef long SDW;                        // 有符号整型,32位
     12 typedef unsigned long UDW;               // 无符号整型,32位
     13 typedef long long SLL;                    // 有符号长整型,64位
     14 typedef unsigned long long ULL;            // 无符号长整型,64位
     15 typedef char CH;                        // 单个字符
     16 typedef float R32;                        // 单精度浮点数
     17 typedef double R64;                        // 双精度浮点数
     18 
     19 #define Rep(i, n) for (register SDW i = 0; i < (n); ++i)
     20 #define For(i, s, t) for (register SDW i = (s); i <= (t); ++i)
     21 #define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i)
     22 #define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     23 #define ms0(a) memset(a,0,sizeof(a))
     24 #define msI(a) memset(a,0x7f,sizeof(a))
     25 #define LOWBIT(x) ((x)&(-x))
     26 
     27 #define MP make_pair
     28 #define PB push_back
     29 #define ft first
     30 #define sd second
     31 #define ALL(x) x.begin(),x.end()
     32 
     33 #define pr(x) cout << #x << " = " << x << "  "
     34 #define prln(x) cout << #x << " = " << x << endl
     35 
     36 #define lson l , mid , rt << 1 
     37 #define rson mid + 1 , r , rt << 1 | 1
     38 
     39 const ULL mod = 1e9 + 7;                //常用模数(可根据题目需要修改)
     40 const ULL inf = 0x7fffffff;                //用来表示无限大
     41 const ULL infLL = 0x7fffffffffffffffLL;    //用来表示无限大
     42 /*-------------------Define End-------------------*/
     43 
     44 const UDW maxN = 5e5 + 7;
     45 SDW N, Q;
     46 string S; 
     47 SDW ans;
     48 
     49 void output();
     50 
     51 SDW st[maxN << 2];
     52     
     53 inline void pushUp(SDW rt) {
     54     st[rt] = st[rt << 1] | st[rt << 1 | 1];
     55 }
     56 
     57 inline void build(SDW l, SDW r, SDW rt) {
     58     if(l >= r) {
     59         st[rt] = (1 << (S[r] - 'a'));
     60         return;
     61     }
     62     SDW mid = (l + r) >> 1;
     63     build(lson);
     64     build(rson);
     65     pushUp(rt);
     66 }
     67 
     68 // 单点更新 
     69 inline void update(SDW x, SDW y, SDW l, SDW r, SDW rt) {
     70     if(l >= r) {
     71         st[rt] = y;
     72         return;
     73     }
     74     SDW mid = (l + r) >> 1;
     75     if(x <= mid) update(x, y, lson);
     76     else update(x, y, rson);
     77     pushUp(rt);
     78 }
     79 
     80 // 区间查询 
     81 inline SDW query(SDW L, SDW R, SDW l, SDW r, SDW rt) {
     82     if(L <= l && r <= R) return st[rt];
     83     SDW ret = 0;
     84     SDW mid = (l + r) >> 1;
     85     
     86     if(L <= mid) ret |= query(L, R, lson);
     87     if(R > mid) ret |= query(L, R, rson);
     88     return ret;
     89 }
     90 
     91 void input(){
     92     cin >> N >> S >> Q;
     93     S = "#" + S;
     94     build(1, N, 1);
     95 }
     96 
     97 void solve(){
     98     SDW mode;
     99     
    100     Rep(i, Q) {
    101         cin >> mode;
    102         if(mode == 1) {
    103             SDW x;
    104             CH y;
    105             cin >> x >> y;
    106             update(x, (1 << (y - 'a')), 1, N, 1);
    107         }
    108         else if(mode == 2) {
    109             SDW x, y;
    110             cin >> x >> y;
    111             ans = query(x, y, 1, N, 1);
    112             ans = __builtin_popcount(ans);
    113             output();
    114         }
    115     }
    116 }
    117 
    118 void output(){
    119     cout << ans << endl;
    120 }
    121 
    122 int main() {
    123     input();
    124     solve();
    125     return 0;
    126 }
    View Code
  • 相关阅读:
    前端知识点--CSS overflow 属性
    js排序——sort()排序用法
    vue知识点---element el-date-picker 插件默认时间属性default-value怎么赋值?
    vue知识点----element UI+vue关于日期范围选择的操作,picker-options属性的使用
    JS_点击事件_弹出窗口_自动消失
    Echarts +ajax+JSONPObject 实现后台数据图表化
    Floyd弗洛伊德算法
    线程中join方法和Sleep方法的举例
    循环注册十个账号,保证程序重启之后,使用这十个账号都能登录成功
    替换文本文件内容
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/12436066.html
Copyright © 2020-2023  润新知