Code Forces 1030E

來源:互聯網
上載者:User

標籤:span   class   sum   pre   沒有   進位   思路   array   關注   

題目大意

給你n個數,你可以交換一個數的任意二進位位,問你可以選出多少區間經過操作後異或和是0。

思路分析:

根據題目,很容易知道,對於每個數,我們可以無視它的1在那些位置,只要關注它有幾個1即可,如果它的1的數量可以通過加減為0,那麼這個區間就是合法的。

可以看到,兩個數(分別有x,y個1,且x〉y)通過交換位置再進行異或操作,可能獲得的新數中1的數量為y-x,y-x+2,y-x+4,...,x+y-2,x+y。

那麼對於每一個左端點(l),它的合法右端點(r)的數量為sum[r]-sum[l-1]為偶數的r的個數(sum為首碼和數組)。同時,這個區間還要滿足區間內1的數量最多的數(假設它在第k位)要小於sum[k]-sum[l-1]的一半,因為假如說它不滿足這一條件的話,那麼就沒有足夠多的1同它相抵消,也就不會合法。

那麼我們應該如何避免這種狀況呢?

很簡單,可能會是不合法右端點的幾個點(最多64個)直接暴力做就行了。

代碼:
var  a,sum,odd,even:array[0..300000]of longint;  i,j,s,max,n,m:longint;  ans,x:int64;begin  read(n);  for i:=1 to n do  begin    read(x);    while x>0 do    begin      a[i]:=a[i]+x and 1;      x:=x>>1;    end;  end;  for i:=1 to n do  begin    sum[i]:=sum[i-1]+a[i];    odd[i]:=odd[i-1]; even[i]:=even[i-1];    if sum[i]and 1=1 then inc(odd[i]) else inc(even[i]);  end;  for i:=1 to n do    if sum[i-1]and 1=1 then ans:=ans+odd[n]-odd[i-1]      else ans:=ans+even[n]-even[i-1];  writeln(ans);  for i:=1 to n do  begin    if i+64>n then m:=n else m:=i+64;    s:=0; max:=0;    for j:=i to m do    begin      if a[j]>max then max:=a[j];      s:=s+a[j];      if (2*max>s)and(s mod 2=0) then dec(ans);    end;  end;  writeln(ans);end.

 

Code Forces 1030E

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.