zoukankan      html  css  js  c++  java
  • ural1989 单点更新+字符串hash

    正解是双哈希,不过一次哈希也能解决。。

    然后某个数字就对应一个字符串,虽然有些不同串对应同一个数字,但是概率非常小,可以忽略不计。从左到右、从右到左进行两次hash,如果是回文串,那么对应的整数必定存在某种关系(可以理解成相等),对于更新操作,就是单点更新。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #include<algorithm>
    #define ll unsigned long long 
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define maxn 100005
    char s[maxn];
    ll F[maxn+1];
    int len;
    struct node{
        ll suml,sumr;
    }tree[maxn<<2];//区间保存从左到右和从右到左的hash值
    inline void pushup(int rt){
        tree[rt].suml=tree[rt<<1].suml+tree[rt<<1|1].suml;
        tree[rt].sumr=tree[rt<<1].sumr+tree[rt<<1|1].sumr;
    }
    void build(int l,int r,int rt){
        if(l==r){
            tree[rt].suml=F[l-1]*(s[l-1]-'a');
            tree[rt].sumr=F[len-l]*(s[l-1]-'a');
            return;
        }
        int m=l+r>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int pos,int val,int l,int r,int rt){//单点更新
        if(l==r){
            tree[rt].suml=F[l-1]*val;
            tree[rt].sumr=F[len-l]*val;
            return;
        }
        int m=l+r>>1;
        if(pos<=m) update(pos,val,lson);
        else update(pos,val,rson);
        pushup(rt);
    }
    ll suml,sumr;
    void query(int x,int y,int l,int r,int rt){
        if(x<=l && y>=r){
            suml+=tree[rt].suml;
            sumr+=tree[rt].sumr;
            return;
        }
        int m=l+r>>1;
        if(x<=m) query(x,y,lson);
        if(y>m) query(x,y,rson);
    }
    int main(){
        F[0]=1;
        for(int i=1;i<=maxn;i++)
            F[i]=F[i-1]*27;//打表处理
        int q;
        while(scanf("%s",s)!=EOF){
            scanf("%d",&q);
            len=strlen(s);
            build(1,len,1);
            char op[20];
            int x,y;
            while(q--){
                scanf("%s",op);
                if(op[0]=='p'){//查询
                    scanf("%d%d",&x,&y);
                    suml=sumr=0;
                    query(x,y,1,len,1);
                    int k1=x-1;//左到右的长度
                    int k2=len-y;//右到左的区间长度
                    if(k1>k2) sumr*=F[k1-k2];
                    else suml*=F[k2-k1];
    cout<<suml<<" "<<sumr<<endl;
                    if(suml==sumr) puts("YES");
                    else puts("NO");
                }
                else {//单点修改
                    int x;
                    char tmp[2];
                    scanf("%d%s",&x,tmp);
                    update(x,tmp[0]-'a',1,len,1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    python画图axis和axes以及subplot的区别
    LSTM block和cell区别
    go语言之用户输入&类型别名&类型转换
    Go 语言运算符
    go语言的常量
    go语言之数据类型和格式化输出
    go语言之变量
    requests+django+bs4实现一个web微信的功能
    python读取es中的所有数据并计算md5然后进行持久化
    python的os模块fnmatch模块介绍
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9905959.html
Copyright © 2011-2022 走看看