题目描述 给定两个01串,S,T(下标从0开始)。
支持如下3种操作:
修改S第i位的字符,即0->1,1->0.
修改T第i位的字符,即0->1,1->0.
查询S[a..a+l-1],T[b..b+l-1]的相似度。
相似度定义如下:
s,t两个字符串的相似度=sigma_{i=0}^{|s|-1} sim(s[i],t[i])
sim(a,b) 有四个参数p_{0,0},p_{0,1},p_{1,0},p_{1,1}。 sim(a,b)的返回值为p_{a,b}。
输入 第一行一个非空字符串S
第二行一个非空字符串T
第三行一个操作个数Q
接下来Q行,每行为”1 i”,”2 i”或”3 a b l p_{0,0} p_{0,1} p_{1,0} p_{1,1}”
输出 若干行,每行对应每个3操作的答案。
样例输入
1010
6
3 0 0 4 1 2 3 4
1 1
3 0 1 3 4 3 7 6
2 2
3 1 0 2 4 5 3 4
3 1 0 3 8 8 8 8
样例输出
10 19 7 24
提示
【数据范围】10%, |S|,|T|<=1000,Q<=1000
10%, |S|,|T|<=50000,Q<=50000,3操作的p值都为1
10%, |S|,|T|<=50000,Q<=50000,所有操作为3操作且a,b,l相同
20%, |S|,|T|<=50000,Q<=50000,3操作的a,b值为0
50%, |S|,|T|<=100000,Q<=100000,0<=p<=50,由于数据随机生成,可以默认3操作l的期望为|S|/6
压位思想,没15位压成一个十进制数至于询问,可以通过位运算得到,详见代码。
uses math;
var
p:array['0'..'1','0'..'1'] of longint;
s,t:ansistring;
a,b,f1,f2,f:array[0..1000000] of longint;
q,z,x,len1,len2,len,p1,p2,p3,p4,i,ans,al,bl,j:longint;
begin
for i:=0 to 1 << 16-1 do
begin
x:=i;
while x>0 do
begin
f[i]:=f[i]+1;
x:=x and(x-1);
end;
end;
readln(s);
for i:=1 to length(s) do
a[i]:=ord(s[i])-ord('0');
readln(t);
for i:=1 to length(t) do
b[i]:=ord(t[i])-ord('0');
for i:=1 to length(s)-15 do
for j:=0 to 15 do
f1[i]:=f1[i]+a[i+j]<<j;
for i:=1 to length(t)-15 do
for j:=0 to 15 do
f2[i]:=f2[i]+b[i+j]<<j;
readln(q);
len1:=length(s);
len2:=length(t);
for z:=1 to q do
begin
read(x);
if x=1 then
begin
readln(x);
x:=x+1;
a[x]:=a[x] xor 1;
for i:=max(1,x-15) to min(x,len1-15) do
f1[i]:=f1[i] xor (1<<(x-i));
continue;
end;
if x=2 then
begin
readln(x);
x:=x+1;
b[x]:=b[x] xor 1;
for i:=max(1,x-15) to min(x,len2-15) do
f2[i]:=f2[i] xor (1<<(x-i));
continue;
end;
readln(al,bl,len,p1,p2,p3,p4);
ans:=0;
al:=al+1;
bl:=bl+1;
for i:=1 to len div 16 do
begin
ans:=ans+f[(f1[al] xor ((1<<16)-1))and(f2[bl] xor ((1<<16)-1))]*p1;
ans:=ans+f[(f1[al] xor ((1<<16)-1))and f2[bl]]*p2;
ans:=ans+f[f1[al] and(f2[bl] xor ((1<<16)-1))]*p3;
ans:=ans+f[f1[al] and f2[bl]]*p4;
al:=al+16;
bl:=bl+16;
end;
for i:=0 to len mod 16-1 do
begin
if (a[i+al]=0)and(b[i+bl]=0) then ans:=ans+p1;
if (a[i+al]=0)and(b[i+bl]=1) then ans:=ans+p2;
if (a[i+al]=1)and(b[i+bl]=0) then ans:=ans+p3;
if (a[i+al]=1)and(b[i+bl]=1) then ans:=ans+p4;
end;
writeln(ans);
end;
end.