int n, k;
int son[30 * maxn][2], idx;
int v[30 * maxn],a[maxn];
void creat(int u,int pos)
{
int p = 0;
pre(i, 29, 0)
{
int x = u >> i & 1;
if (son[p][x] == 0) son[p][x] = ++idx;
p = son[p][x];
v[p] = pos;
}
return;
}
int ser(int u)
{
int ans = -1;
int res = 0;
int p = 0;
pre(i, 29, 0)
{
int x = u >> i & 1;
if (son[p][!x])
{
p = son[p][!x];
res = res + (1 << i);
if (res >= k)
ans = max(ans, v[p]);
}
else
{
p = son[p][x];
//if (res >= k)
// ans = max(ans, v[p]);
}
}
return ans;
}
signed main()
{
//ios::sync_with_stdio(0);
//cin.tie(0),cout.tie(0);
int t = read();
while (t--)
{
n = read(), k = read();
rep(i, 0, 30 * n)
son[i][0] = son[i][1] = 0;
idx = 0;
rep(i, 1, n) a[i] = read();
int sum = 0;
int l = -1, r = -1;
int res = 0,minn = inf;
rep(i, 1, n)
{
sum = sum ^ a[i];
if ((res = ser(sum)) != -1)
{
if (minn > (i - res))
{
//see1(i);
minn = i - res;
l = res + 1;
r = i;
}
}
creat(sum, i);
}
if (~l)
{
printf("%d %d\n", l, r);
}
else out(-1);
}
return 0;
}
1009
Let’s call a weighted connected undirected graph of n vertices and m edges KD-Graph, if the following conditions fulfill:
* n vertices are strictly divided into K groups, each group contains at least one vertice
* if vertices p and q ( p ≠ q ) are in the same group, there must be at least one path between p and q meet the max value in this path is less than or equal to D.
* if vertices p and q ( p ≠ q ) are in different groups, there can’t be any path between p and q meet the max value in this path is less than or equal to D.
You are given a weighted connected undirected graph G of n vertices and m edges and an integer K.
Your task is find the minimum non-negative D which can make there is a way to divide the n vertices into K groups makes G satisfy the definition of KD-Graph.Or −1 if there is no such D exist.
int n, m, k;
int fa[maxn];
struct nod
{
int a, b, c;
bool operator < (const nod& b) const&
{
return c < b.c;
}
}mp[5*maxn];
int find(int x)
{
if (fa[x] != x) fa[x] = find(fa[x]);
return fa[x];
}
void solve()
{
rep(i, 1, n) fa[i] = i;
sort(mp + 1, mp + 1 + m);
int now = n,ans = 0;
rep(i, 1, m)
{
if (mp[i].c > ans) // 在将某一阶段合并完成后,再去比较
{
if (now == k)
{
out(ans);
return;
}
}
if ( find(mp[i].a) == find(mp[i].b) ) continue;
now--; // 现在有的集合数减少
fa[find(mp[i].a)] = find(mp[i].b);
ans = mp[i].c;
}
printf("%d\n", now == k ? ans : -1); //最后有一次是没有判断的
return ;
}
signed main()
{
//ios::sync_with_stdio(0);
//cin.tie(0),cout.tie(0);
int t = read();
while (t--)
{
n = read(), m = read(), k = read();
rep(i, 1, m)
{
int x = read(), y = read(), z = read();
mp[i] = { x,y,z };
}
solve();
}
return 0;
}