zoukankan      html  css  js  c++  java
  • Gym

    题意:给定字符串char[],以及Q个操作,操作有三种:

        1:pos,chr:把pos位置的字符改为chr

        2:pos:问以pos为中心的回文串长度为多长。

        3:pos:问以pos,pos+1为中心的回文串长度为多长。

    思路:用hash表示一段字符串或者连续子串。我们用BIT记录hash前缀和,那么也可以用BIT修改前缀和。然后blabla,乱搞就行了。

    当然为了保险,最好用双hash。

    (此题暴力也可以过!

    暴力代码:3962ms

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=100010;
    char c[maxn],t;
    int main()
    {
        int N,Q,opt,x;
        scanf("%s%d",c+1,&Q); N=strlen(c+1);
        while(Q--){
            scanf("%d%d",&opt,&x);
            if(opt==1){
                scanf(" %c",&t); c[x]=t;
            }
            else if(opt==2){
                int i=x,j=x;
                while(i-1>=1&&j+1<=N&&c[i-1]==c[j+1]) i--,j++;
                printf("%d
    ",j-i+1);
            }
            else {
                if(c[x]!=c[x+1]) { puts("-1"); continue;}
                int i=x,j=x+1;
                while(i-1>=1&&j+1<=N&&c[i-1]==c[j+1]) i--,j++;
                printf("%d
    ",j-i+1);
            }
        }
        return 0;
    }
    View Code

    hash+BIT+二分:93ms(目前排第一?

    #include<bits/stdc++.h>
    #define uint unsigned int
    using namespace std;
    const int maxn=100010;
    const uint seed=131;
    char c[maxn]; uint sum[maxn][2],p[maxn]; int N;
    uint query(int x,int opt){
        uint res=0; while(x) {
            res+=sum[x][opt]; x-=(-x)&x;
        } return res;
    }
    bool check(int L,int R)
    {
        if(L<1||R>N) return false;
        uint h1=(query(R,0)-query(L-1,0))*p[L-1];
        uint h2=(query(R,1)-query(L-1,1))*p[N-R];
        if(h1==h2) return true; return false;
    }
    int main()
    {
        int Q,i,j;
        scanf("%s%d",c+1,&Q); N=strlen(c+1);
        p[0]=1; 
        for(i=1;i<=N;i++) p[i]=p[i-1]*seed;
        for(i=1;i<=N;i++){
            for(j=i;j<=N;j+=(-j)&j) sum[j][0]+=p[N-i]*c[i];
            for(j=i;j<=N;j+=(-j)&j) sum[j][1]+=p[i-1]*c[i];
        }
        int opt,x,L,R,Mid,ans; char chr;
        while(Q--){
            scanf("%d%d",&opt,&x);
            if(opt==1){
                scanf(" %c",&chr);
                for(j=x;j<=N;j+=(-j)&j) sum[j][0]+=p[N-x]*(chr-c[x]);
                for(j=x;j<=N;j+=(-j)&j) sum[j][1]+=p[x-1]*(chr-c[x]);
                c[x]=chr;
            }
            else if(opt==2){
                L=0; R=N; ans=1;
                while(L<=R){
                    Mid=(L+R)>>1;
                    if(check(x-Mid,x+Mid)) ans=Mid,L=Mid+1;
                    else R=Mid-1;
                }
                printf("%d
    ",ans*2+1);
            }
            else{
                L=0; R=N; ans=-1;
                while(L<=R){
                    Mid=(L+R)>>1;
                    if(check(x-Mid,x+1+Mid)) ans=Mid,L=Mid+1;
                    else R=Mid-1;
                }
                printf("%d
    ",ans==-1?-1:ans*2+2);
            }
        }
        return 0;
    }
  • 相关阅读:
    母版页中对控件ID的处理
    使用Gridview绑定数据库中的图片
    导出Excel表格时,如何把数据库表中的编号转换成配置文件中的"汉字"
    ORA01502: 索引'P_ABCD.PK_WEB_BASE'或这类索引的分区处于不可用状态
    Oracle 把触发器说透
    规模估算失准 软件开发成空中楼阁
    在web开发中的三个层次使用事务
    oninput,onpropertychange,onchange的用法和区别
    Oracle 把游标说透
    在datatable中,在指定位置插入列
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9508189.html
Copyright © 2011-2022 走看看