• hdu 4339 Query 一道挺好的树状数组题(树状数组+二分思想)


    题意:首先给了两个字符串,然后有两种类型的操作,第一种:1 a i c 你应该把第i个字符串的第a个字符变成c;第二种:2 i 就是问你从第i个字符开始两个字符串连续的最长的相等长度。

    思路:利用树状数组更新和求和,对于第二种操作就是利用二分求得的连续最长的长度。

    代码实现:

    #include<iostream>
    #include<cstring>
    using namespace std;
    char str1[1000001],str2[1000001];
    int a[1000001],len1,len2;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void build(int x,int num)//构造树状数组
    {
       while(x<=len1)
       {
           a[x]=a[x]+num;
           x=x+lowbit(x);
       }
    }
    int sum(int x)//求和
    {
        int s=0;
        while(x>=1)
        {
            s=s+a[x];
            x=x-lowbit(x);
        }
        return s;
    }
    int main()
    {
        int T,nima,i,Q,x1,x2,x3,nima1,nima2;
        char temp;
        while(scanf("%d",&T)!=EOF)
        {
            getchar();
            nima=0;
            while(T--)
            {
              nima++;
              scanf("%s%s",str1+1,str2+1);//数组下标从1开始
              printf("Case %d:\n",nima);
              len1=strlen(str1+1);
              len2=strlen(str2+1);
              len1=len1>len2?len2:len1;//去两者中短的
              for(i=0;i<=len1;i++)
                  a[i]=0;//树状数组的初始化
              for(i=1;i<=len1;i++)
                  if(str1[i]==str2[i])
                     build(i,1);
              scanf("%d",&Q);
              while(Q--)
              {
                  scanf("%d",&x1);
                  if(x1==1)
                  {
                      scanf("%d%d %c",&x2,&x3,&temp);
                      getchar();
                      if(x3+1<=len1)
                      {
                          if(x2==1)//对第一个字符串进行操作
                          {
                             if(str1[x3+1]==str2[x3+1]&&str2[x3+1]!=temp)
                                build(x3+1,-1);
                             else if(str1[x3+1]!=str2[x3+1]&&str2[x3+1]==temp)
                                 build(x3+1,1);
                             str1[x3+1]=temp;
                          }
                          else
                          {
                              if(str1[x3+1]==str2[x3+1]&&str1[x3+1]!=temp)
                                build(x3+1,-1);
                              else if(str1[x3+1]!=str2[x3+1]&&str1[x3+1]==temp)
                                build(x3+1,1);
                              str2[x3+1]=temp;
                          }
                      }
                  }
                  else
                  {
                      scanf("%d",&x2);
                      if(x2>len1)
                          printf("%d\n",0);
                      else
                      {
                          nima1=x2+1;nima2=len1;
                          while(nima1<=nima2)//二分思想
                          {
                             int mid=(nima1+nima2)/2;
                             if((sum(mid)-sum(nima1-1))==(mid-nima1+1))//左边连续
                                 nima1=mid+1;
                             else//左边不连续
                                 nima2=mid-1;
                          }
                          printf("%d\n",nima2-x2);
                      }
                  }
              }
            }
        }
        return 0;
    }
  • 相关阅读:
    C++ istringstream总结
    C++各数据类型的最值
    AcWing 机器人跳跃问题 二分
    蓝桥杯 矩形面积交
    蓝桥杯 完美的代价
    蓝桥杯 数的读法
    国内 镜像 下载
    redis的pipline使用
    MySQL额外操作
    sql强化演练( goods 表练习)
  • 原文地址:https://www.cnblogs.com/jiangjing/p/2868113.html
Copyright © 2020-2023  润新知