空之碎物
超级无敌结论题。与图论无关的两只
按位考虑。发现最终的数一个二进制位上一定能被写成
Observation
证明:显然。
Observation
证明:考虑
Observation
证明:取
构造是容易的,不妨让剩下的数按照
Observation
上述已经证明
证明:
显然
如果存在
唯一的反例出现在
于是剩下的就不难了,从高位到低位贪心,如果这一位
时间复杂度:
- 长度
=3 :O(1) - 长度
>26 :O(n) - 长度
\in\{2,4,5,..,26\} :O(n\log^2 V) (n\log V 个区间,每个区间计算需要\log V )
参考代码:
#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _rep(i,a,b) for(int i=(a);i>=(b);i--)
#define subset(i,x) for(int i=(x);i;i=((i-1)&x))
#define pi pair<int,int>
#define arr(a) array<int,(a)>
#define F fflush(stdout)
#define RE return puts("-1"),void()
#define cases(_) while((_)--) solve();
using namespace std;
const int mod=998244353;
inline void ckmin(int& x,int y){x=min(x,y);}
inline void ckmax(int& x,int y){x=max(x,y);}
inline void add(int& x,int y){x=(x%mod+y%mod+mod)%mod;}
inline void mul(int& x,int y){x=(x%mod)*(y%mod)%mod;}
const int N=200005,BIT=25;
int _=1,n,a[N],t[BIT+5],flg[BIT+5],vis[N],ans,res,tmp,nxt[N],pre[N];
inline void add(int x){
if(x==0) return;
rep(o,0,BIT) if((a[x]>>o)&1) t[o]++,flg[o]=x;
}
inline int f(int x,int y){
int res=0;
rep(o,0,BIT) if((x>>o)&1 && !((y>>o)&1)) res+=(1<<o);
return res;
}
inline int calc(int x,int y,int z){
int r1=f(f(x,y),z),r2=f(f(x,z),y),r3=f(f(y,z),x),r4=f(f(y,x),z),r5=f(f(z,y),x),r6=f(f(z,x),y);
int c1=f(z,f(x,y)),c2=f(y,f(x,z)),c3=f(x,f(y,z)),c4=f(z,f(y,x)),c5=f(x,f(z,y)),c6=f(y,f(z,x));
int a1=max(max(max(r1,r2),r3),max(max(r4,r5),r6));
int a2=max(max(max(c1,c2),c3),max(max(c4,c5),c6));
return max(a1,a2);
}
void solve(){
scanf("%lld",&n),a[0]=-1;
rep(i,1,n) scanf("%lld",&a[i]);
rep(l,1,n){
int mx=0;
rep(o,0,BIT) t[o]=0,flg[o]=0;
rep(r,l,min(l+30,n)){
if(a[r]<=a[mx]) add(r);
else add(mx),mx=r;
rep(o,l,r) vis[o]=0;
int sum=r-l,res1=0;
_rep(o,BIT,0) if(t[o]==1 && (a[mx]>>o)&1){
sum-=(vis[flg[o]]==0);
if(sum==0) sum++,res1+=(1ll<<o);
else vis[flg[o]]=1;
}
if(r-l!=2) add(ans,a[mx]-res1);
else add(ans,calc(a[l],a[l+1],a[l+2]));
add(tmp,a[mx]);
}
}
fill(nxt+1,nxt+n+1,n+1);
stack<int> st;
rep(i,1,n){
while(!st.empty() && a[i]>a[st.top()]) nxt[st.top()]=i,st.pop();
st.push(i);
}
while(!st.empty()) st.pop();
_rep(i,n,1){
while(!st.empty() && a[i]>=a[st.top()]) pre[st.top()]=i,st.pop();
st.push(i);
}
rep(i,1,n) add(res,(i-pre[i])*(nxt[i]-i)%mod*a[i]);
add(ans,res-tmp);
printf("%lld\n",ans);
}
signed main(){
cases(_);
return 0;
}