B - Operation线性基入门:【条件动态维护区间线性基】【前缀线性基】

题目链接VJ
题目链接HDU
(本文是对%%%%%的学习笔记,同时使用了本题作为例题学。)
线性基真是个简单而强大的东西,然而我因为很少遇到线性基的题目基本没有怎么学习,线性基是一个基于贪心的数据处理技巧。
如果定义原序列通过若干个元素异或的到的新集合为序列的异或域,那么线性基就是一个异或域与原序列异或域相同的极小集合。

线性基三大性质:

1.原序列里面的任意一个数都可以由线性基里面的一些数异或得到
2.线性基里面的任意一些数异或起来都不能得到 0 00
3.线性基里面的数的个数唯一,并且在保持性质一的前提下,数的个数是最少的

首先是线性基能够维护的东西:

序列异或
(序列取若干个数异或起来的最值,即异或域的极值 :)
最小值:线性基最小值。
最大值:从高位到低位贪心取,以代码来说为:

if((res^d[i])>res)res^=d[i];

接下来就是线性基进阶技巧:

序列异或第k小
时间复杂度在于预处理 ( l o g A i ) 2 (log{A_i})^2 (logAi)2;
预处理就是让线性基的数位性质变化成为:当且仅当当前位取了,当前位的二进制位上才会为1;

void work()//处理线性基
{
	for(int i=1;i<=60;i++)
	for(int j=1;j<=i;j++)
	if(d[i]&(1ll<<(j-1)))d[i]^=d[j-1];
}
ll k_th(ll k)
{
	if(k==1&&tot<n)return 0;//特判一下,假如k=1,并且原来的序列可以异或出0,就要返回0,tot表示线性基中的元素个数,n表示序列长度
	if(tot<n)k--;//类似上面,去掉0的情况,因为线性基中只能异或出不为0的解
	work();
	ll ans=0;
	for(int i=0;i<=60;i++)
	if(d[i]!=0)
	{
		if(k%2==1)ans^=d[i];
		k/=2;
	}
}

当序列经过了处理,那么很显然相当于:
d 0 d 1 d 2 d 3 … … d t d_0d_1d_2d_3……d_t d0d1d2d3dt
其中 d i d_i di表示第i位的线性基取/不取。排名k自然也变成了d序列;
如果k = 10 1 ( 2 ) 101_(2) 101(2)
即:
第一小的线性基元素取了即: d 0 = 1 d_0=1 d0=1
第二小的线性基元素不取即: d 1 = 0 d_1=0 d1=0
第三小的线性基元素取了即: d 2 = 1 d_2=1 d2=1
于是第i位线性基元素贡献为: ( 1 < < i & k ) ∗ d [ i ] (1<<i\&k)*d[i] (1<<i&k)d[i];

动态维护序列线性基(带插入和删除)
因为过于少见,暂且备板,挂起来。


回到这个题:
本题希望维护区间线性基;修改操作只有在最右边放置新的数(仅有两种操作,一种是a[++n] = x,一种是query(l,r))

采用一个技巧:
线性基的性质之一就是只要保持线性基大小不变,数具体是哪些是可以变的。于是使用前缀线性基:
查询l,r,只需要使用 1 , r 1,r 1,r的线性基减去 1 , ( l − 1 ) 1,(l-1) 1,(l1)的影响即可;
那么如何去除1,(l-1)的影响;替换掉线性基里面的数,记录每一个数在原序列中的位置,如果某一位可以使用多种线性基:为了消除先后影响,一律使用最新的,即每一个位的线性基元素都应该是可选元素集合中位置最靠后面的。
换而言之:以d[i][j]表示1-i的线性基第j位;
pos[i][j]表示1-i的线性基第j位用的数本体在原序列中位置;

void _insert(int now,int k,int val)//a[loc] = k;
{
	for(int i =29;i>=0;--i){p[now][i] =p[now-1][i];loc[now][i]=loc[now-1][i];}
	for(int i =29;i>=0;--i)
	{
		if( !((1<<i)&val) )continue;
		if(!p[now][i])
		{
			p[now][i] = val;
			loc[now][i] = k;
			break;
		}
		else if(loc[now][i]<k)
		{//当前更新
			swap(loc[now][i],k);
			swap(p[now][i],val);
		}
		val^=p[now][i];
	}
}

插入函数就要做出一点改变,注意到for中多了一个loc[now][i]<k的情况:即当前位置自己本不应该插入,但是是个旧版本的线性基元素,为了让线性基有先后区别,只需要把当前数赶走就行了,来个乾坤大挪移:
swap两次把应该插入的数置换掉;
然后原序列的前缀线性基用到的数都是尽可能靠后的。那么如何消除影响:
统计区间异或最值的时候只需要跳过旧版本即可:

int query(int l,int r)
{
	int res=0;
	for(int i =29;i>=0;--i)
	{
		if(loc[r][i]>=l&&(res^p[r][i])>res)res^=p[r][i];
	}
	return res;
}

增加了一个判断:loc[r][i]>=l;

如此本题就算做完了;
总结:
前缀线性基能够维护出区间线性基,不支持删改操作,但是可以在序列后面增数。

C:\Users\1\PycharmProjects\pythonProject1\.venv\Scripts\python.exe C:\Users\1\PycharmProjects\pythonProject1\future.py 找到文件: 光伏 找到文件: 风能 找到文件: 日前电价 找到文件: 高压负荷 找到文件: 实时电价 找到文件: 气象 正在读取数据文件... 成功读取: 光伏,数据形状: (2880, 2) 光伏数据样例: DATA_TIME DATA_VALUE_光伏 0 2025-01-01 00:00:00 -0.054 1 2025-01-01 01:00:00 -0.054 -------------------------------------------------- 成功读取: 风能,数据形状: (2880, 2) 风能数据样例: DATA_TIME DATA_VALUE_风能 0 2025-01-01 00:00:00 77.7221 1 2025-01-01 01:00:00 41.9552 -------------------------------------------------- 成功读取: 日前电价,数据形状: (9888, 3) 日前电价数据样例: 时间 价格 开停 0 2025-01-01 00:15:00 377.0 开 1 2025-01-01 00:30:00 372.0 开 -------------------------------------------------- 成功读取: 高压负荷,数据形状: (35712, 2) 高压负荷数据样例: DATA_TIME DATA_VALUE 0 2025-03-01 00:00:00 -429.9219 1 2025-03-01 00:05:00 -456.6538 -------------------------------------------------- 成功读取: 实时电价,数据形状: (9888, 2) 实时电价数据样例: 时间 价格 0 2025-01-01 00:15:00 377.0 1 2025-01-01 00:30:00 372.0 -------------------------------------------------- 成功读取: 气象,数据形状: (3181, 8) 气象数据样例: DATA_TIME TEMPERATURE ... SUNLIGHT_INTENSITY ISOBARIC 0 2025-01-01 00:00:00 -1.0 ... NaN NaN 1 2025-01-01 01:00:00 -1.0 ... NaN NaN [2 rows x 8 columns] -------------------------------------------------- 清洗 光伏 数据... 缺失值处理报告: DATA_VALUE_光伏: 1个缺失值已处理 异常值处理报告: DATA_VALUE_光伏: 45个异常值已处理 光伏 清洗完成,处理后形状: (2880, 2) 清洗 风能 数据... 风能 清洗完成,处理后形状: (2880, 2) 清洗 日前电价 数据... 异常值处理报告: 价格: 248个异常值已处理 日前电价 清洗完成,处理后形状: (9888, 3) 清洗 高压负荷 数据... 高压负荷 清洗完成,处理后形状: (35712, 2) 清洗 实时电价 数据... 异常值处理报告: 价格: 301个异常值已处理 实时电价 清洗完成,处理后形状: (9888, 2) 清洗 气象 数据... 缺失值处理报告: WIND_DIRECTION: 113个缺失值已处理 SUNLIGHT_INTENSITY: 113个缺失值已处理 ISOBARIC: 113个缺失值已处理 异常值处理报告: WIND_SPEED: 112个异常值已处理 WIND_DIRECTION: 257个异常值已处理 HUMIDITY: 140个异常值已处理 ISOBARIC: 24个异常值已处理 气象 清洗完成,处理后形状: (3181, 8) 整合数据... C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:77: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(mode_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) C:\Users\1\PycharmProjects\pythonProject1\future.py:73: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method. The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy. For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object. df[col].fillna(median_val, inplace=True) 合并后数据形状: (9888, 14) 合并后数据列名: ['时间', '价格_实时', '价格_日前', '竞价状态', 'DATA_VALUE_光伏', 'DATA_VALUE_风能', 'DATA_VALUE', 'TEMPERATURE', 'WIND_SPEED', 'WIND_DIRECTION', 'HUMIDITY', 'RAIN_RATE', 'SUNLIGHT_INTENSITY', 'ISOBARIC'] 进行描述性分析... 基本统计量已保存至 analysis_results/基本统计量.csv Traceback (most recent call last): File "C:\Users\1\PycharmProjects\pythonProject1\.venv\Lib\site-packages\pandas\core\indexes\base.py", line 3812, in get_loc return self._engine.get_loc(casted_key) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "pandas/_libs/index.pyx", line 167, in pandas._libs.index.IndexEngine.get_loc File "pandas/_libs/index.pyx", line 196, in pandas._libs.index.IndexEngine.get_loc File "pandas/_libs/hashtable_class_helper.pxi", line 7088, in pandas._libs.hashtable.PyObjectHashTable.get_item File "pandas/_libs/hashtable_class_helper.pxi", line 7096, in pandas._libs.hashtable.PyObjectHashTable.get_item KeyError: '实时电价' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\1\PycharmProjects\pythonProject1\future.py", line 184, in <module> plt.plot(merged["时间"], merged["实时电价"], label="实时电价", alpha=0.7) ~~~~~~^^^^^^^^^^^^ File "C:\Users\1\PycharmProjects\pythonProject1\.venv\Lib\site-packages\pandas\core\frame.py", line 4113, in __getitem__ indexer = self.columns.get_loc(key) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\1\PycharmProjects\pythonProject1\.venv\Lib\site-packages\pandas\core\indexes\base.py", line 3819, in get_loc raise KeyError(key) from err KeyError: '实时电价'
最新发布
12-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值