E. Kefa and Watch hash 线段树

2015-09-28 14:11:36 by opas

 这题给的是一个字符串 把其中一些子串给取出来 判断是否是周期为d的字符串  还需要把 其中的一个区间完全变成一个数 ,然后在查询,我们把每个字符串进行hash 不管结果怎么样hash 然后进行区区间判断 。。 还是存在概率性的错误的

#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn=100005;
const LL mod0 =1000000007;
const LL mod1 =1000000009;
LL powd[2][maxn],digitpow[2][10][maxn];
void init()
{
   powd[0][0]=powd[1][0]=1;
   for(LL i=1; i<=100000; i++)
    {
         powd[0][i]=( powd[0][i-1] * 10 )%mod0;
         powd[1][i]=( powd[1][i-1] * 10 )%mod1;

         for(int j=0; j<10; j++)
            {
                digitpow[0][j][i]=( digitpow[0][j][i-1]*10+j )%mod0;
                digitpow[1][j][i]=( digitpow[1][j][i-1]*10+j )%mod1;
            }
    }
}
char str[maxn];
struct Itree
{
       LL mark[maxn*4],v[2][maxn*4],ans[2];
       int cL,cR,num;
       void maintain(int L, int R, int o)
       {
            int mid=(L+R)>>1;
            v[0][o]=( v[0][o*2] * powd[0][R-mid] + v[0][o*2+1] )%mod0;
            v[1][o]=( v[1][o*2] * powd[1][R-mid] + v[1][o*2+1] )%mod1;
       }
       void build(int L, int R, int o)
       {
            mark[o]=-1;
            if(L==R){
                v[0][o]=v[1][o]=str[L-1]-'0'; return ;
            }
            int mid=(L+R)>>1;
            build(L,mid,o*2);
            build(mid+1,R,o*2+1);
            maintain(L,R,o);
       }
       void qper(int L, int R,int n, LL &ans0,LL &ans1)
       {
            cL=L;cR=R; ans[0]=ans[1]=0;num=0;
            query(1,n,1);
            ans0=ans[0]; ans1=ans[1];
       }
       void pushdown(int L, int R, int o)
       {
            if(mark[o]!=-1)
                {
                       int mid=(L+R)>>1;
                       mark[o*2]=mark[o*2+1]=mark[o];

                       v[0][o*2]=digitpow[0][mark[o]][ mid-L+1 ];
                       v[1][o*2]=digitpow[1][mark[o]][ mid-L+1 ];

                       v[0][o*2+1]=digitpow[0][mark[o]][ R-mid ];
                       v[1][o*2+1]=digitpow[1][mark[o]][ R-mid ];

                       mark[o]=-1;
                }
       }
       void query(int L, int R, int o)
       {
            if(cL<=L&&R<=cR)
            {
                 ans[0]=(ans[0]*powd[0][R-L+1]+v[0][o])%mod0;
                 ans[1]=(ans[1]*powd[1][R-L+1]+v[1][o])%mod1;
                return ;
            }
            pushdown(L,R,o);
            int mid=(L+R)>>1;
            if(cL<=mid)query(L,mid,o*2);
            if(cR>mid)query(mid+1,R,o*2+1);
       }
       void update(int L, int R, int o)
       {
            if(cL<=L&&R<=cR)
                {
                    mark[o]=num;
                    v[0][o]=digitpow[0][num][R-L+1];
                    v[1][o]=digitpow[1][num][R-L+1];
                    return ;
                }
             pushdown(L,R,o);
             int mid=(L+R)>>1;
             if(cL<=mid)update(L,mid,o*2);
             if(cR>mid)update(mid+1,R,o*2+1);
             maintain(L,R,o);
       }
}T;
int main()
{
     init();
     int n,m,k;
     while(scanf("%d%d%d",&n,&m,&k)==3)
        {
            scanf("%s",str);
            T.build(1,n,1);
            m+=k;
            while(m--){
                int op,L,R,V;
                scanf("%d%d%d%d",&op,&L,&R,&V);

                 if(op==1){
                  T.cL=L;T.cR=R;  T.num=V;
                  T.update(1,n,1);
                 }else{
                     if((R-L+1)<=V){
                        puts("YES");
                     }else
                     if( ( R - L + 1 ) <= 2 * V )
                        {

                             int len=R-L+1-V;
                             LL a10,a11,a20,a21;
                             T.qper(L,L+len-1,n,a10,a11);
                             T.qper(R-len+1,R,n,a20,a21);
                             if(a10==a20&&a11==a21) puts("YES");
                             else puts("NO");

                        }else
                        {
                            if((R-L+1)%V == 0){
                              int d=(R-L+1)/V;
                              int len = (d-1)*V;
                              LL a10,a11,a20,a21;
                              T.qper(L,L+len-1,n,a10,a11);
                              T.qper(R-len+1,R,n,a20,a21);
                              if(a10==a20&&a11==a21) puts("YES");
                              else puts("NO");
                            }
                            else{
                              int d=(R-L+1)/V;
                              int len = (d-1)*V;
                              int tail=(R-L+1)-V*d;
                              LL a10,a11,a20,a21;
                              T.qper(L,L+len-1,n,a10,a11);
                              T.qper(L+V,L+V+len-1,n,a20,a21);
                              if(a10==a20&&a11==a21) {
                                 T.qper(L,L+tail-1,n,a10,a11);
                                 T.qper(R-tail+1,R,n,a20,a21);
                                 if(a10==a20&&a11==a21)
                                    puts("YES");
                                 else puts("NO");
                              }
                              else puts("NO");



                            }
                        }

                 }





                }
        }
    return 0;
}
View Code

 

posted @ 2015-09-28 14:18  来自大山深处的菜鸟  阅读(204)  评论(0编辑  收藏  举报