ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[20220318联考] 无向图

2022-03-18 17:08:49  阅读:142  来源: 互联网

标签:le return val 20220318 int TT ql 无向 联考


前言

典中典之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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有