日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【无码专区11】异或2(结论 / 推式子 + 哈希hash + 大整数高精度 加减乘除重载考察)

發布時間:2023/12/3 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【无码专区11】异或2(结论 / 推式子 + 哈希hash + 大整数高精度 加减乘除重载考察) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本題已自我實現。但仍歸于無碼專區

problem

∑i=1n?1i?(n?i)\sum_{i=1}^{n-1}i\bigoplus (n-i)i=1n?1?i?(n?i)

20%,n≤1e6;;50%,n≤1e9;;70%,n≤1e18;;100%,n≤1050020\%,n\le 1e6;;50\%,n\le 1e9;;70\%,n\le 1e18;;100\%,n\le 10^{500}20%,n1e6;;50%,n1e9;;70%,n1e18;;100%,n10500。

1s,128MB1s,128MB1s,128MB。

my idea

當看到 nnn 的數據范圍且不取模的那一刻,我就知道大整數跑不掉了。

最基礎 20%20\%20% ,直接暴力做。

會發現 i?(n?i)=(n?i)?ii\bigoplus (n-i)=(n-i)\bigoplus ii?(n?i)=(n?i)?i,所以其實上是 2∑i=1n?12i?(n?i)2\sum_{i=1}^{\frac{n-1}{2}}i\bigoplus (n-i)2i=12n?1??i?(n?i) 大概這樣的。

我曾試圖每一位單獨考慮,但很難下手。

直觀地,我能感受到是 logloglog 的正解。

但由于對異或計算法則的不了解,我覺得自己并不能做出這道題來。

solution

i?(n?i)=(n?i)?i?2∑i=1n?12i?(n?i)i\bigoplus (n-i)=(n-i)\bigoplus i\Rightarrow 2\sum_{i=1}^{\frac{n-1}{2}}i\bigoplus (n-i)i?(n?i)=(n?i)?i?2i=12n?1??i?(n?i),真的就是正解的關鍵所在。

如果我在考場上繼續細想,應該是能找到規律的。

  • n=2k+1n=2k+1n=2k+1

    f(n)=∑i=1n?1i?(n?i)=2∑i=1k2i?(2k+1?2i)f(n)=\sum_{i=1}^{n-1}i\bigoplus (n-i)=2\sum_{i=1}^k2i\bigoplus(2k+1-2i)f(n)=i=1n?1?i?(n?i)=2i=1k?2i?(2k+1?2i)

    因為 2i,2k,2k?2i2i,2k,2k-2i2i,2k,2k?2i 均為偶數,所以每次異或,202^020 為是 111。

    ?f(n)=2∑i=1k2i?(2k?2i)+2k\Rightarrow f(n)=2\sum_{i=1}^k2i\bigoplus (2k-2i)+2k?f(n)=2i=1k?2i?(2k?2i)+2k

    參與異或的只有偶數,整體右移 111

    ?f(n)=4∑i=1ki?(n?i)+2k\Rightarrow f(n)=4\sum_{i=1}^ki\bigoplus (n-i)+2k?f(n)=4i=1k?i?(n?i)+2k

    感覺很有機會轉化成一半的子問題,把 i=ki=ki=k 提出來。

    ?f(n)=4∑i=1k?1i?(n?i)+4(k?0)+2k\Rightarrow f(n)=4\sum_{i=1}^{k-1}i\bigoplus (n-i)+4(k\bigoplus0)+2k?f(n)=4i=1k?1?i?(n?i)+4(k?0)+2k

    ?f(n)=4f(k)+6k\Rightarrow f(n)=4f(k)+6k?f(n)=4f(k)+6k

  • n=2kn=2kn=2k

    f(n)=∑i=1n?1i?(n?i)=∑i=1k2i?(2k?2i)+∑i=1k(2i?1)?(2k?2i+1)f(n)=\sum_{i=1}^{n-1}i\bigoplus (n-i)=\sum_{i=1}^k2i\bigoplus(2k-2i)+\sum_{i=1}^k(2i-1)\bigoplus(2k-2i+1)f(n)=i=1n?1?i?(n?i)=i=1k?2i?(2k?2i)+i=1k?(2i?1)?(2k?2i+1)

    ?f(n)=2f(k)+∑i=0k?1(2i+1)?(2k?2i?1)\Rightarrow f(n)=2f(k)+\sum_{i=0}^{k-1}(2i+1)\bigoplus(2k-2i-1)?f(n)=2f(k)+i=0k?1?(2i+1)?(2k?2i?1)

    ?f(n)=2f(k)+∑i=0k?1(2i+1)?[2(k?1)?2i+1]\Rightarrow f(n)=2f(k)+\sum_{i=0}^{k-1}(2i+1)\bigoplus[2(k-1)-2i+1]?f(n)=2f(k)+i=0k?1?(2i+1)?[2(k?1)?2i+1]

    2i+12i+12i+1 是奇數,2(k?1)?2i+12(k-1)-2i+12(k?1)?2i+1 也是奇數,所以異或后 202^020 二進制位一定是 000。

    那么就不管了,直接整體右移 111。

    ?f(n)=2f(k)+2∑i=0k?1i?(k?1?i)\Rightarrow f(n)=2f(k)+2\sum_{i=0}^{k-1}i\bigoplus(k-1-i)?f(n)=2f(k)+2i=0k?1?i?(k?1?i)

    感覺很有機會轉化成一半的子問題,把 i=0,i=k?1i=0,i=k-1i=0,i=k?1 提出來。

    ?f(n)=2f(k)+4(k?1)+2∑i=1k?2i?(k?1?i)\Rightarrow f(n)=2f(k)+4(k-1)+2\sum_{i=1}^{k-2}i\bigoplus(k-1-i)?f(n)=2f(k)+4(k?1)+2i=1k?2?i?(k?1?i)

    ?f(n)=2f(k)+2f(k?1)+4k?4\Rightarrow f(n)=2f(k)+2f(k-1)+4k-4?f(n)=2f(k)+2f(k?1)+4k?4

直接記憶化搜索,最后就是要寫大整數加減乘除賦值了。

trick
因為我曾試圖用 map<Int,Int> 來記錄 f[n]f[n]f[n],但是沒寫過。
重載 SLT 內部運算真的搞崩了。
所以我將字符串進行了自然溢出的 hash
map<ull,Int> 就不用管重載 map 的 < 了。
最后就是空間比較小,我寫的是數組,不是 vector 存大數。
只知道 1000 太小,1500 太大。

code

#include <bits/stdc++.h> using namespace std; #define ull unsigned long long struct Int {int len, v[1300]; ull Hash;Int() { len = 1; memset( v, 0, sizeof( v ) ); }Int( int x ) { memset( v, 0, sizeof( v ) ); v[len = 1] = x; calc(); }void read() {char s = getchar(); len = 0;while( '0' <= s and s <= '9' ) {v[++ len] = s ^ 48;s = getchar();}reverse( v + 1, v + len + 1 );}void print() { for( int i = len;i;i -- ) printf( "%d", v[i] ); puts(""); }void calc() { Hash = 1; for( int i = 1;i <= len;i ++ ) Hash = Hash * 131 + v[i]; }Int operator + ( Int x ) {Int ans;int ip = 1;while( ip <= len or ip <= x.len ) {ans.v[ip + 1] = ( v[ip] + x.v[ip] + ans.v[ip] ) / 10;ans.v[ip] = ( v[ip] + x.v[ip] + ans.v[ip] ) % 10;ip ++;}while( ip > 1 and ! ans.v[ip] ) ip --;ans.len = ip;ans.calc();return ans;}Int operator - ( int k ) {Int ans;Int x( k );int ip = 1;while( ip <= len or ip <= x.len ) {ans.v[ip] = v[ip] - x.v[ip];if( ans.v[ip] < 0 ) v[ip + 1] --, ans.v[ip] += 10;ip ++;}while( ip > 1 and ! ans.v[ip] ) ip --;ans.len = ip;ans.calc();return ans;}Int operator * ( int x ) {Int ans;ans.len = len + 1;for( int i = 1;i <= len;i ++ ) {ans.v[i + 1] = ( ans.v[i] + v[i] * x ) / 10;ans.v[i] = ( v[i] * x + ans.v[i] ) % 10;}while( ans.len > 1 and ! ans.v[ans.len] ) ans.len --;ans.calc();return ans;}Int operator / ( int x ) {Int ans; int k = 0;ans.len = len;for( int i = len;i;i -- ) {k = ( k << 1 ) + ( k << 3 ) + v[i];ans.v[i] = k / x;k %= x;}while( ans.len > 1 and ! ans.v[ans.len] ) ans.len --;ans.calc();return ans;}Int operator = ( Int x ) {len = x.len;Hash = x.Hash;memcpy( v, x.v, sizeof( x.v ) );return *this;}}; map < ull, Int > f;Int dfs( Int n ) {if( f.count( n.Hash ) ) return f[n.Hash];if( n.len == 1 and ( n.v[1] == 1 or n.v[1] == 0 ) ) return (Int)0;if( n.v[1] & 1 ) f[n.Hash] = dfs( n / 2 ) * 4 + n / 2 * 6;else f[n.Hash] = dfs( n / 2 ) * 2 + dfs( n / 2 - 1 ) * 2 + n * 2 - 4;return f[n.Hash]; }signed main() {freopen( "rox.in", "r", stdin );freopen( "rox.out", "w", stdout );Int n;n.read(); dfs( n ).print();return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的【无码专区11】异或2(结论 / 推式子 + 哈希hash + 大整数高精度 加减乘除重载考察)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。