其他分享
首页 > 其他分享> > [20220318联考] 无向图

[20220318联考] 无向图

作者:互联网

前言

典中典之sb题复杂度算错。

题目

没有链接

有个集合 \(S\) ,初始为空,还有一堆数字 \([0,2^n)\),然后有 \(m\) 个操作:

  1. 往集合 \(S\) 加一个没有的数。
  2. 删除 \(S\) 中一个存在的数。

如果 \(u\oplus v=x,x\in S\),那么 \(u,v\) 之间有边,每次操作后问最大连通块大小。

\(1\le n\le 30;1\le m\le 10^5.\)

讲解

首先你发现就是求线性基的大小,记为 \(|G|\),那么答案就是 \(2^{|G|}\)。

处理出每个数出现的时间然后直接线段树分治就可以水过去了,时间复杂度是 \(O(n\log_2^2n)\)。

当然可以用可删线性基,大概就是多维护一下时间,贪心用出现删除时间晚的,可以做到 \(O(n\log_2n)\)。

代码

//12252024832524
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std; 

typedef long long LL;
const int MAXN = 100005;
int n,m;
unordered_map<int,int> ID;

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

#define lc (x<<1)
#define rc (x<<1|1)
int t[MAXN<<2][30],cnt[MAXN<<2];
void ins(int x,int val){
	for(int i = 29;i >= 0;-- i)
		if(val >> i & 1){
			if(!t[x][i]) {t[x][i] = val;++cnt[x];break;}
			else val ^= t[x][i];
		}
}
void Add(int x,int l,int r,int ql,int qr,int val){
	if(ql <= l && r <= qr) {ins(x,val);return;}
	int mid = (l+r) >> 1;
	if(ql <= mid) Add(lc,l,mid,ql,qr,val);
	if(mid+1 <= qr) Add(rc,mid+1,r,ql,qr,val);
}
void solve(int x,int l,int r){
	if(x != 1) for(int i = 29;i >= 0;-- i) if(t[x>>1][i]) ins(x,t[x>>1][i]);
	if(l == r) {Put(1ll << cnt[x],'\n');return;}
	int mid = (l+r) >> 1;
	solve(lc,l,mid); solve(rc,mid+1,r);
}

int main()
{
//	freopen("xor.in","r",stdin);
//	freopen("xor.out","w",stdout);
	n = Read(); m = Read();
	for(int i = 1;i <= m;++ i){
		int opt = Read(),val = Read();
		if(opt == 1) ID[val] = i;
		else Add(1,1,m,ID[val],i-1,val),ID[val] = 0;
	}
	for(auto &A : ID) if(A.second) Add(1,1,m,A.second,m,A.first);
	solve(1,1,m);
	return 0;
}

后记

当然这篇文章主要是为了摘要把想写的英文歌词写完(两句放一篇太丑了)。

歌是 Guns For Hire

标签:le,return,val,20220318,int,TT,ql,无向,联考
来源: https://www.cnblogs.com/PPLPPL/p/16022567.html