zoukankan      html  css  js  c++  java
  • 二分+树状数组/线段树(区间更新) HDOJ 4339 Query

    题目传送门

    题意:给两串字符串,操作1:替换其中一个字符串的某个位置的字符 操作2:查询从p开始相等的最长连续长度

    分析:树状数组可以维护一个区间内公共长度(连续)的情况,查询时用二分查找最远的端点即可。还可以用线段树去做,线段树能处理的问题很多,这题只要往右区间合并就行了。

    收获:1.线段树的区间合并又做一题(虽然我写的还没AC) 2. 树状数组写起来方便又奇效!

    代码1(树状数组):

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015-8-26 9:46:09
    * File Name     :I.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e6 + 10;
    const int Q = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    char s1[N], s2[N];
    int L;
    struct BIT   {
        int c[N];
        void init(void) {
            memset (c, 0, sizeof (c));
        }
        void updata(int i, int x)   {
            while (i <= L)   {
                c[i] += x;  i += (i & (-i));
            }
        }
        int query(int i)    {
            int ret = 0;
            while (i)   {
                ret += c[i];    i -= (i & (-i));
            }
            return ret;
        }
        int bsearch(int p, int l, int r)    {
            while (l <= r)  {
                int mid = (l + r) >> 1;
                if (query (mid) - query (p-1) == mid - p + 1)   l = mid + 1;
                else    r = mid - 1;
            }
            return l - p;
        }
    }bit;
    
    int main(void)    {
        int T, cas = 0; scanf ("%d", &T);
        while (T--) {
            scanf ("%s%s", s1 + 1, s2 + 1);
            int q;  scanf ("%d", &q);
            int len1 = strlen (s1 + 1), len2 = strlen (s2 + 1);
            L = min (len1, len2);
    
            bit.init ();
            for (int i=1; i<=L; ++i)    {
                if (s1[i] == s2[i]) bit.updata (i, 1);
            }
            printf ("Case %d:
    ", ++cas);
            while (q--) {
                int op; scanf ("%d", &op);
                if (op == 1)    {
                    int x, p;   char c; scanf ("%d%d %c", &x, &p, &c);
                    ++p;
                    if (p > L) continue;
                    bool same = (s1[p] == s2[p]);
                    if (x == 1) {
                        s1[p] = c;
                        if (same && s1[p] != s2[p])   bit.updata (p, -1);
                        else if (!same && s1[p] == s2[p])   bit.updata (p, 1);
                    }
                    else    { 
                        s2[p] = c;
                        if (same && s1[p] != s2[p])   bit.updata (p, -1);
                        else if (!same && s1[p] == s2[p])   bit.updata (p, 1);
                    }
                }
                else    {
                    int p;  scanf ("%d", &p);
                    ++p;
                    if (p > L) {
                        puts ("0"); continue;
                    }
                    printf ("%d
    ", bit.bsearch (p, p, L));
                }
            }
        }
    
        return 0;
    }
    

    代码2(线段树):

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015-8-26 9:46:09
    * File Name     :I.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e6 + 10;
    const int Q = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    char s1[N], s2[N];
    struct ST   {
        int sum[N<<2];
        void push_up(int rt, int len)    {      //sum[rt<<1]表示从左子树线段左端点开始最长连续的公共的长度,如果全是公共的,
            if (sum[rt<<1] == len - (len >> 1)) sum[rt] = sum[rt<<1] + sum[rt<<1|1];        //合并右子树的线段长度
            else    sum[rt] = sum[rt<<1];
        }
        void build(int l, int r, int rt)    {
            if (l == r) {
                sum[rt] = s1[l] == s2[r] ? 1 : 0;
                return ;
            }
            int mid = (l + r) >> 1;
            build (lson);   build (rson);
            push_up (rt, r - l + 1);
        }
        void updata(int p, int c, int l, int r, int rt)    {
            if (l == r) {
                sum[rt] = c;  return ;
            }
            int mid = (l + r) >> 1;
            if (p <= mid)   updata (p, c, lson);
            else    updata (p, c, rson);
            push_up (rt, r - l + 1);
        }
        int query(int p, int l, int r, int rt)  {
            if (l == r) return sum[rt];
            int mid = (l + r) >> 1;
            if (p <= mid)   {
                int ret = query (p, lson);
                if (p + ret - 1 == mid) return ret + sum[rt<<1|1];
                else    return ret;
            }
            else    return query (p, rson);
        }
    }st;
    
    int main(void)    {
        int T, cas = 0; scanf ("%d", &T);
        while (T--) {
            scanf ("%s%s", s1 + 1, s2 + 1);
            int q;  scanf ("%d", &q);
            int len1 = strlen (s1 + 1), len2 = strlen (s2 + 1);
            int mn = min (len1, len2);
            st.build (1, mn, 1);
    
            printf ("Case %d:
    ", ++cas);
            while (q--) {
                int op; scanf ("%d", &op);
                if (op == 1)    {
                    int x, p;   char c; scanf ("%d%d %c", &x, &p, &c);
                    ++p;
                    if (p > mn) continue;                       //特殊情况特判
                    if (x == 1) {
                        s1[p] = c;
                    }
                    else    {
                        s2[p] = c;
                    }
                    st.updata (p, (s1[p] == s2[p]), 1, mn, 1);
                }
                else    {
                    int p;  scanf ("%d", &p);
                    ++p;
                    if (p > mn) {                               //特殊情况特判
                        puts ("0"); continue;
                    }
                    printf ("%d
    ", st.query (p, 1, mn, 1));
                }
            }
        }
    
        return 0;
    }
    

    代码3(unAC):

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015-8-26 9:46:09
    * File Name     :I.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e6 + 10;
    const int Q = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    char s1[N], s2[N];
    struct ST   {
        int sum[N<<2], lsum[N<<2], rsum[N<<2];
        void push_up(int rt, int len)    {
            lsum[rt] = lsum[rt<<1];
            rsum[rt] = rsum[rt<<1|1];
            sum[rt] = max (sum[rt<<1], sum[rt<<1|1]);
            if (lsum[rt] == len - (len >> 1))   lsum[rt] += lsum[rt<<1|1];
            if (rsum[rt] == len >> 1)   rsum[rt] += rsum[rt<<1];
            sum[rt] = max (rsum[rt<<1] + lsum[rt<<1|1], max (sum[rt<<1], sum[rt<<1|1]));
        }
        void build(int l, int r, int rt)    {
            if (l == r) {
                sum[rt] = lsum[rt] = rsum[rt] = s1[l] == s2[r] ? 1 : 0;
                return ;
            }
            int mid = (l + r) >> 1;
            build (lson);   build (rson);
            push_up (rt, r - l + 1);
        }
        void updata(int p, int c, int l, int r, int rt)    {
            if (l == r) {
                sum[rt] = lsum[rt] = rsum[rt] = c;  return ;
            }
            int mid = (l + r) >> 1;
            if (p <= mid)   updata (p, c, lson);
            else    updata (p, c, rson);
            push_up (rt, r - l + 1);
        }
        int query(int p, int l, int r, int rt)  {
            if (l == r) return sum[rt];
            int mid = (l + r) >> 1;
            if (p <= mid)   {
                if (p + rsum[rt<<1] - 1 >= mid)    return mid - p + 1 + query (p, rson);
                else    return query (p, lson);
            }
            else    return query (p, lson);
        }
    }st;
    
    int main(void)    {
        int T, cas = 0; scanf ("%d", &T);
        while (T--) {
            scanf ("%s%s", s1 + 1, s2 + 1);
            int q;  scanf ("%d", &q);
            int len1 = strlen (s1 + 1), len2 = strlen (s2 + 1);
            int mn = min (len1, len2);
            st.build (1, mn, 1);
    
            printf ("Case %d:
    ", ++cas);
            while (q--) {
                int op; scanf ("%d", &op);
                if (op == 1)    {
                    int x, p;   char c; scanf ("%d%d %c", &x, &p, &c);
                    if (p + 1 > mn) continue;
                    if (x == 1) {
                        s1[p+1] = c;
                    }
                    else    {
                        s2[p+1] = c;
                    }
                    st.updata (p+1, (s1[p+1] == s2[p+1]), 1, mn, 1);
                }
                else    {
                    int p;  scanf ("%d", &p);
                    if (p + 1 > mn) {
                        puts ("0"); continue;
                    }
                    printf ("%d
    ", st.query (p + 1, 1, mn, 1));
                }
            }
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    前辈的经验
    ES6 的新特性
    jQuery 事件对象的属性和方法
    ECMAScript 6 入门
    浏览器的加载与页面性能优化
    ajax 基于 jquery 简单的 ajax 请求
    浏览器加载、解析、渲染的过程
    浏览器的加载和解析的过程,以及如何加快 HTML 的加载速度
    【经典问题】当你输入一个网址的时候,实际会发生什么?
    总结 IE 下的一些 BUG
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4760643.html
Copyright © 2011-2022 走看看