您的位置:首页 > 其它

E. Kefa and Watch hash 线段树

2015-09-28 14:18 393 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: