bzoj 2115 Xor 線性基 貪心

2022-04-30 04:42:10 字數 1825 閱讀 3149

題目傳送門

這是個通往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可以變換...