cf776G.Sherlock and the Encrypted Data
題意:對于一個16進制數x,把x的各個數位拿出來,設其為t1,t2,...,定義s(x)為2^t1|2^t2|...,如x=0x3e53,則s(x)=2^3|2^14|2^5|2^3=16424.給出q組詢問l,r(l,r也是16進制數,不超過15位),求[l,r]中有多少個數x滿足x^s(x)<x.
這題題解寫的是個狀壓數位dp,但是蒟蒻不會數位dp,自己YY了一個做法.
首先,將[l,r]的詢問拆成2個前綴和,考慮到十六進制數減1并不方便,可以轉化為solve(r)-solve(l),再特判一下l滿不滿足要求.
考慮求出[0,upper]間的答案.將二進制位從低位向高位,從0開始編號.觀察x和s(x)的二進制表示,可以發現當且僅當s(x)的最高位1所在的數位上x也為1時,x^s(x)<x.考慮從0到15枚舉這個數位的位置id,下面只需求出不超過upper的數中有多少個數在id位為1,且所有數位都不超過id,且有至少一個數位等于id.發現最后一個條件不好處理,可以將詢問拆成2個:設solve(upper,id,lim)表示不超過upper的數中有多少個數在id位為1,且所有數位都不超過lim.所求答案即為solve(upper,id,id)-solve(upper,id,id-1).這個東西是可以掃幾遍upper討論一通求出來的.實現上細節非常惡心比較多.
1 program cf776G; 2 const number=['a'..'f','0'..'9']; 3 list:array[0..15]of char=('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'); 4 var q,i:longint; 5 l,r:string; 6 num:array[char] of longint; 7 ch:char; 8 procedure getstr(var s:string); 9 var ch:char; 10 begin 11 s:=''; 12 read(ch); 13 while not (ch in number) do read(ch); 14 while ch in number do 15 begin 16 s:=s+ch; 17 read(ch); 18 end; 19 end; 20 function check(const x:string):longint; 21 var i:longint; 22 t,this:int64; 23 begin 24 this:=0; 25 for i:=1 to length(x) do this:=this*16+num[x[i]]; 26 t:=0; 27 for i:=1 to length(x) do t:=t or (1 shl num[x[i]]); 28 exit(ord(this xor t<this)); 29 end; 30 function solve2(const upper:string;id,up:longint):int64; 31 var upp,ans:int64; 32 i,this,t:longint; 33 sw:array[0..30] of longint; 34 pow:array[0..20] of int64; 35 begin 36 upp:=0; 37 for i:=1 to length(upper) do upp:=upp*16+num[upper[i]]; 38 for i:=1 to length(upper) do sw[length(upper)-i]:=num[upper[i]]; 39 if(1 shl (id mod 4)>up)or(1 shl id>upp)or(up<0) then exit(0); 40 t:=0; 41 for this:=0 to up do if this and (1 shl (id mod 4))>0 then inc(t); 42 ans:=0; 43 pow[0]:=1; 44 for i:=1 to length(upper) do pow[i]:=pow[i-1]*(up+1); 45 for i:=length(upper)-1 downto 0 do 46 if i=id div 4 then 47 begin 48 if up<sw[i] then 49 begin 50 ans:=ans+t*pow[i]; 51 exit(ans); 52 end; 53 for this:=0 to sw[i]-1 do if this and (1 shl (id mod 4))>0 then 54 ans:=ans+pow[i]; 55 if sw[i] and (1 shl (id mod 4))=0 then exit(ans); 56 end else 57 begin 58 if up<sw[i] then 59 begin 60 if i>id div 4 then ans:=ans+pow[i]*t else ans:=ans+pow[i+1]; 61 exit(ans); 62 end else 63 begin 64 if i>id div 4 then ans:=ans+pow[i-1]*sw[i]*t 65 else ans:=ans+pow[i]*sw[i]; 66 end; 67 end; 68 inc(ans); 69 exit(ans); 70 end; 71 function solve(const upper:string):int64; 72 var ans:int64; 73 k:longint; 74 begin 75 ans:=0; 76 for k:=0 to 15 do 77 ans:=ans+solve2(upper,k,k)-solve2(upper,k,k-1); 78 exit(ans); 79 end; 80 begin 81 for i:=0 to 15 do num[list[i]]:=i; 82 readln(q); 83 for i:=1 to q do 84 begin 85 getstr(l);getstr(r); 86 writeln(solve(r)-solve(l)+check(l)); 87 end; 88 end.View Code
?
轉載于:https://www.cnblogs.com/lkmcfj/p/6473927.html
總結
以上是生活随笔為你收集整理的cf776G.Sherlock and the Encrypted Data的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浮雕多少钱了一平方呀?
- 下一篇: 源码-0205-02--聊天布局