題目傳送門
這是個通往vjudge的蟲洞
這是個通往bzoj的蟲洞
題目大意
問點$1$到點$n$的最大異或路徑。
因為重複走一條邊後,它的貢獻會被消去。所以這條路徑中有貢獻的邊可以看成是一條$1$到$n$的簡單路徑加上若干個環。
因此可以找任意一條路徑,然後找出所有環扔進線性基跑出最大異或和。
但是找出所有環可能會t掉,但是仔細畫圖發現,並不需要找出所有環,例如:
在上圖中,你並不需找出所有的環,只用找出1 - 3 - 4 - 2和3 - 5 - 6 - 4這兩個環,它們異或後就能得到環1 - 3 - 5 - 6 - 4 - 2。
至於找這個環,可以用dfs生成樹來找。當出現返祖邊的時候就意味著找到了乙個環。
然後可以記乙個異或的字首和,這樣就可以$o(1)$算出環上的邊權的異或和。
對於任意一條路徑得到的異或和如果為$s$,那麼我們只需要考慮線性基的每一位上,如果異或上它,能夠使答案變大,就異或上它。
因為線性基不能保證最大的異或和由之前扔進去的所有數得到,所以必須這麼貪一下心。
這樣的正確性顯然。
1/**
2* bzoj
3* problem#2115
4* accepted
5* time: 740ms
6* memory: 7040k7*/
8 #include 9
#ifndef win32
10#define auto "%lld"
11#else
12#define auto "%i64d"
13#endif
1415
using
namespace
std;
16 typedef bool
boolean;
1718
#define ll long long
1920 typedef class
linearbasis
2526
void
insert(ll x) 39}
40}4142
ll getans(ll ans)
48}linearbasis;
4950 typedef class
edge
56}edge;
5758 typedef class
mapmanager
65 mapmanager(int n, int m):ce(0
) 70
71void addedge(int u, int
v, ll w)
7576 edge& operator (int
p) 79
}mapmanager;
8081
intn, m;
82 ll *xs;
83mapmanager g;
84linearbasis lb;
85 boolean *vis;
8687 inline void
init()
98}
99100
void dfs(int
p) 110
}111
}112
113 inline void
solve()
119120
intmain()
BZOJ 2115 線性基)詳解
第一行包含兩個整數n和 m,表示該無向圖中點的數目與邊的數目。接下來m 行描述 m 條邊,每行三個整數si,ti di,表示 si 與ti之間存在 一條權值為 di的無向邊。圖中可能有重邊或自環。僅包含乙個整數,表示最大的xor和 十進位制結果 注意輸出後加換行回車。5 71 2 2 1 3 2 2...
線性基 BZOJ 4269 再見Xor
划水中。遲早要完 顯然要線性基。考慮求k k 大。對於基的每乙個位置,因為其最高非零位就是位置標號,那看一下 k role presentation k k的這一位是否為 1 1 看是否要異或上 或者不異或 使得這一位得到的答案較大。include define show x cerr x x en...
xor序列 (線性基)
小a有n個數,他提出了乙個很有意思的問題 他想知道對於任意的x,y,能否將x與這n個數中的任意多個數異或任意多次後變為y 第一行為乙個整數n,表示元素個數 第二行一行包含n個整數,分別代表序列中的元素 第三行為乙個整數q,表示詢問次數 接下來q行,每行兩個數x,y,含義如題所示輸出q行,若x可以變換...