五一集训Day2
A
转化后的题意是维护带删除线性基,2e7个操作(插入和删除),并在每次操作完后求线性基的大小。
我们把每个添加操作的数的存在时间区间求出来,题意保证了每个数不会同时有两个。在插入的时候同时维护线性基上每一位的删除时间Ti,使得Ti由高往低递减。这样在删除的时候只会删除最低位的,不会造成影响,所以直接删。具体方法是插入一个数的时候,如果当前位有值(ai)且Ti<Tnow,把当前的值和时间都换成这一位的,然后正常构造。这样仍能满足线性基的性质(最小,能表示出所有数)
这个trick挺实用的,贴一下代码。
namespace solve3{
int a[32],T[32];int tt;
inline void insert(int x,int t){
for(int i=31;i>=0;--i){
if((x>>i)&1){
if(a[i]==0){
a[i]=x;
T[i]=t;
tt++;
break;
}else{
if(t>T[i]){
swap(a[i],x);
swap(t,T[i]);
}
}
x^=a[i];
}
}
}
void del(int x){
for(int i=31;i>=0;--i){
if(T[i]==x){
a[i]=T[i]=0,tt--;break;
}
}
}
inline int getans(){
return tt;
}
unordered_map<int,int>mp;int las[N];
int p[N],w[N];
void solve(){
FOR(i,1,q){
int opt=read(),x=read();p[i]=opt;w[i]=x;
if(opt^2){
las[i]=q+1;
mp[x]=i;
}
else{
las[mp[x]]=i;
}
}
FOR(i,1,q){
if(p[i]^2){
insert(w[i],las[i]);
}else del(i);
ans^=(1<<(n-getans()));
//printf("%d\n",(1<<(n-lb.getans())));
}
print(ans);
}
}
C
\[ans(l,r)=\prod_{\text{p is a prime}}\prod_{k>0}(P^k)^{f(p^k)-f(p^{k+1})} \]
\[=\prod_{\text{p is a prime}}p^{\sum_{k>0}k(f(p^k)-f(p^{k+1}))} \]
\[=\prod_{\text{p is a prime}}p^{\sum_{k>0}f(p^k)} \]
于是莫队可以\(NM^{0.5}logW\),考虑继续优化
首先预处理出每个数的大质数因子,莫队直接算
然后预处理每个\(p^k\)的倍数的前缀和,个数为\(O(\frac {\sqrt w}{\log w} )\)
总复杂度为\(O((N+M)\frac {\sqrt w}{\log w})\)
B
每次枚举一个不相交与当前集合的子集,令这个集合的元素值相等。我们从小到大枚举子集的值,显然这个值不超过每个元素上限的最小值。总复杂度\(O(3^N*N)\),FWT可以做到\(O(2^N*N^3)\),不是很会...