zoukankan      html  css  js  c++  java
  • 宁波多校(一) D题 COLORS的字符串挑战(线段树+hash+二分)

    题意:给定一个字符串,每个操作1修改字符串上的某个值

    2.给x,y,询问以x开头和以y开头的两个后缀字符串的最长前缀的大小。

    经典的线段树维护hash值,之后对于每个询问,用二分查询答案,带了两个log

    比赛的时候一直被卡,结束后加了一行如果第一个字母不等就略过的优化就卡过了,太伤了。

    #include<cstring>
    #include<cstdio>
    #include<set>
    using namespace std;
    const int N = 100010, P = 13131;
    typedef unsigned long long LL;
    struct note
    {
        int l,r;
        LL h;
    }tr[N * 4];
    char s[N];
    LL p[N];
    int n;
    int x,y;
    void build(int u, int l, int r)
    {
        tr[u] = {l, r};
        if(l == r)
        {
            tr[u].h = s[l];
            return;
        }
        int mid = l + r >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        tr[u].h = tr[u << 1].h * p[r - mid] + tr[u << 1 | 1].h;
    }
    void modify(int u, int x, char c)
    {
        if(tr[u].l == tr[u].r)
        {
            tr[u].h = c;
            return;
        }
    
        int mid = tr[u].l + tr[u].r >> 1;
        if(x <= mid)  modify(u << 1, x, c);
        else  modify(u << 1 | 1, x, c);
    
        tr[u].h = tr[u << 1].h * p[tr[u].r - mid] + tr[u << 1 | 1].h;
    }
    LL query(int u, int l, int r)
    {
        if(tr[u].l >= l and tr[u].r <= r)  return tr[u].h;
    
        int mid = tr[u].l + tr[u].r >> 1;
        if(r <= mid)  return query(u << 1, l, r);
        else if(l > mid)  return query(u << 1 | 1, l, r);
        return query(u << 1, l, mid) * p[r - mid] + query(u << 1 | 1, l, r);
    }
    bool check(int mid){
        if(query(1,x,x+mid-1)==query(1,y,y+mid-1))
            return true;
        return false;
    }
    int main()
    {
        p[0] = 1;
        for(int i = 1; i < N; i ++)  p[i] = p[i - 1] * P;
    
        int T;
        scanf("%d", &T);
        for(int t = 1; t <= T; t ++)
        {
            int n;
            scanf("%d", &n);
            scanf("%s", s);
            build(1, 0, n - 1);
            int m;
            scanf("%d", &m);
            while(m --)
            {
                int opt;
                scanf("%d", &opt);
                if(opt==2)
                {
                    scanf("%d%d",&x,&y);
                    if(x>y)
                        swap(x,y);
                    if(s[x]!=s[y]){
                        printf("0
    ");
                        continue;
                    }
                    int l=0,r=n-x;
                    while(l<r){
                        int mid=l+r+1>>1;
                        if(check(mid))
                            l=mid;
                        else
                            r=mid-1;
                    }
                    printf("%d
    ",l);
                }
                else
                {
                    int x;
                    char c[2];
                    scanf("%d%s", &x, c);
                    modify(1, x, c[0]);
                    s[x]=c[0];
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    数据库性能测试---前阿里数据库团队资深DBA杨奇龙
    阿里云 MYSQL 与 PG(丁奇与德哥)
    RHEL6中ulimit的nproc限制
    Linux下文件描述符
    Linux中的文件描述符与打开文件之间的关系------------每天进步一点点系列
    5.6 太多分区引起OOM
    Linux lsof命令使用小结
    重现PHP Core的调用栈
    用GDB排查Python程序故障
    mysql 索引优化
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13237126.html
Copyright © 2011-2022 走看看