Description
Input
Output
Sample Input
123 1234 234 2345 5
Sample Output
470244
Data Constraint
题解
这道题真的是一道传说中的想法超级简单而实现起来细节超级多超级繁琐的题。
调了我两天
废话不多说。
30%直接暴力
60%据说可以用trie做。然而我不会
100%
我们观察一下题目。
我们发现,我们设一个函数f(a,b)表示0 ~ a和0 ~ b这范围内的两两xor值为m的方案。
答案即为:
我们又发现,题目实际上可以用类似于数形dp的套路,把一个数分成“1001101……”的形式,然后处理。
那么对于两个上界a,b。我们如何统计0 ~ a与0 ~ b的值呢?
首先把a,b拆成二进制,然后我们就从高位往低位枚举;
我们找到当前位置为1的位置,把当前位置看做是0,那么左边就是全部与原来的a(b)相同的,右边则是不定的,怎么填数字都是可以的(比上界小)。
(红色为确定的,蓝色为当前点,要变成0,黄色为不定的)
然后,我们考虑把当前这两种情况给xor起来,就会发现:
那么,就会分成三种情况:红色为确定的,绿色为一半确定,一半不定,黄色是全部不确定的。
我们就看看如何记录答案。
对于一个新的C的值,我们要使得C确定时有多少方案,那么红色确定,绿色虽然不确定,但要符合C的值,所以也是确定的。
然而对于这个黄色,它要变成一个确定的,那么就有(p为黄色段的长度)
我们再回到题目,发现A xor B|m,那么我们当前的这个C就是在(q为绿色段的长度,op为红色段的值。)到
也就是:
我们就要在上面的两个式子中找到是m倍数的个数再乘上即可。
关于找r~l之间是m倍数的个数:r/m-(l-1)/m
很多细节,自己慢慢玩:
var
i,j,k,l,n:longint;
l1,r1,l2,r2,m,answer:int64;
mi:array[0..63] of int64;
mo:int64=998244353;
function f(a,b:int64):int64;
var
i,j,k,upa,upb:longint;
ta,tb,ja,jb:array[0..100] of longint;
op,sa,sb,an,l,r,pp:int64;
begin
fillchar(ja,sizeof(ja),0);
fillchar(jb,sizeof(jb),0);
op:=a;upa:=0;upb:=0;
while op>0 do
begin
op:=op div 2;
inc(upa);
end;
op:=a;
j:=1;
for i:=upa downto 1 do
begin
ja[i]:=op mod 2;
op:=op div 2;
end;
op:=b;
while op>0 do
begin
op:=op div 2;
inc(upb);
end;
op:=b;
j:=1;
for i:=upb downto 1 do
begin
jb[i]:=op mod 2;
op:=op div 2;
end;
f:=0;
sa:=0;
for i:=1 to upa do
begin
if ja[i]=1 then
begin
ta[i]:=0;
sb:=0;
for j:=1 to upb do
begin
if jb[j]=1 then
begin
tb[j]:=0;
if (upa-i)>(upb-j) then
begin
op:=sa xor (sb div mi[(upa-i)-(upb-j)]);
an:=mi[upb-j] mod mo;
op:=op mod m;
l:=op*mi[upa-i];
r:=op*mi[upa-i]+mi[upa-i]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end
else
begin
op:=sb xor (sa div mi[(upb-j)-(upa-i)]);
an:=mi[upa-i] mod mo;
op:=op mod m;
l:=op*mi[upb-j];
r:=op*mi[upb-j]+mi[upb-j]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end;
end;
tb[j]:=jb[j];
sb:=(sb+tb[j])*2;
end;
fillchar(tb,sizeof(tb),0);
end;
ta[i]:=ja[i];
sa:=(sa+ta[i])*2;
end;
fillchar(tb,sizeof(tb),0);
ta:=ja;
sa:=a;
sb:=0;
if upa>0 then
for j:=1 to upb do
begin
if jb[j]=1 then
begin
tb[j]:=0;
if (upa-i)>(upb-j) then
begin
op:=sa xor (sb div mi[(upa-i)-(upb-j)]);
an:=mi[upb-j] mod mo;
op:=op mod m;
l:=op*mi[upa-i];
r:=op*mi[upa-i]+mi[upa-i]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end
else
begin
op:=sb xor (sa div mi[(upb-j)-(upa-i)]);
an:=mi[upa-i] mod mo;
op:=op mod m;
l:=op*mi[upb-j];
r:=op*mi[upb-j]+mi[upb-j]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end;
end;
tb[j]:=jb[j];
sb:=(sb+tb[j])*2;
end;
tb:=jb;
fillchar(ta,sizeof(ta),0);
sb:=b;
sa:=0;
if upb>0 then
for i:=1 to upa do
begin
if ja[i]=1 then
begin
ta[i]:=0;
if (upa-i)>(upb-j) then
begin
op:=sa xor (sb div mi[(upa-i)-(upb-j)]);
an:=mi[upb-j] mod mo;
op:=op mod m;
l:=op*mi[upa-i];
r:=op*mi[upa-i]+mi[upa-i]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end
else
begin
op:=sb xor (sa div mi[(upb-j)-(upa-i)]);
an:=mi[upa-i] mod mo;
op:=op mod m;
l:=op*mi[upb-j];
r:=op*mi[upb-j]+mi[upb-j]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end;
end;
ta[i]:=ja[i];
sa:=(sa+ta[i])*2;
end;
ta:=ja;
tb:=jb;
sa:=a;sb:=b;
if (upa>0) and (upb>0) then
begin
if (upa-i)>(upb-j) then
begin
op:=sa xor (sb div mi[(upa-i)-(upb-j)]);
an:=mi[upb-j] mod mo;
op:=op mod m;
l:=op*mi[upa-i];
r:=op*mi[upa-i]+mi[upa-i]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end
else
begin
op:=sb xor (sa div mi[(upb-j)-(upa-i)]);
an:=mi[upa-i] mod mo;
op:=op mod m;
l:=op*mi[upb-j];
r:=op*mi[upb-j]+mi[upb-j]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end;
end;
if (a=0) and (b>0) then
begin
sb:=0;
for j:=1 to upb do
begin
if jb[j]=1 then
begin
tb[j]:=0;
op:=sb xor (sa div mi[(upb-j)]);
an:=1;
op:=op mod m;
l:=op*mi[upb-j];
r:=op*mi[upb-j]+mi[upb-j]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end;
tb[j]:=jb[j];
sb:=(sb+tb[j])*2;
end;
if (b xor 0) mod m=0 then inc(f);
end
else
if (a>0) and (b=0) then
begin
sa:=0;
for i:=1 to upa do
begin
if ja[i]=1 then
begin
ta[i]:=0;
op:=sa xor (sb div mi[(upa-i)]);
an:=1;
op:=op mod m;
l:=op*mi[upa-i];
r:=op*mi[upa-i]+mi[upa-i]-1;
pp:=(r div m-(l-1) div m) mod mo;
if l=0 then inc(pp);
f:=(f+(pp*an) mod mo) mod mo;
end;
ta[i]:=ja[i];
sa:=(sa+ta[i])*2;
end;
if (a xor 0) mod m=0 then inc(f);
end
else
if (a=0) and (b=0) then
begin
f:=1;
end;
end;
begin
assign(input,'mod.in');reset(input);
assign(output,'mod.out');rewrite(output);
mi[0]:=1;
for i:=1 to 62 do
begin
mi[i]:=mi[i-1]*2;
end;
readln(l1,r1,l2,r2,m);
writeln((f(r1,r2)-f(l1-1,r2)-f(r1,l2-1)+f(l1-1,l2-1)+mo) mod mo);
end.