• [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

  • 相关阅读:
    maven工程下的“run as application”
    Spark机器配置计算
    数学思路
    关联和依赖
    spark数据倾斜
    windows的DOS窗口如何修改大小
    MySQL的索引创建、删除
    使用composer命令创建laravel项目命令详解
    Windows平台查看端口占用情况
    使用composer安装laravel
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/16022567.html
Copyright © 2020-2023  润新知