#include<bits/stdc++.h>
using namespace std;
#define int long long
const int n=1e5+11;
const int mod=998244353;
int a,b,c[n],d,e[n][32][4];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>a;
while(a--){
cin>>b;
for(int i=1;i<=b;i++)
{
cin>>c[i];
}
stack<int>t;
vector<int>p;
for(int i=1;i<=b;i++)
{
if(t.empty()||c[t.top()]<=c[i])
{
t.push(i);
p.push_back(i);
}
else
{
while(!t.empty()&&c[t.top()]>c[i])
{
t.pop();
}
if(t.empty())
{
p.push_back(1);
}
else
p.push_back(t.top()+1);
t.push(i);
}
}
while(!t.empty())
{
t.pop();
}
vector<int>k;
for(int i=b;i>=1;i--)
{
if(t.empty()||c[t.top()]<c[i])
{
t.push(i);
k.push_back(i);
}
else
{
while(!t.empty()&&c[t.top()]>=c[i])
{
t.pop();
}
if(t.empty())
k.push_back(b);
else
k.push_back(t.top()-1);
t.push(i);
}
}
reverse(k.begin(),k.end());
int w=0;
for(int i=0;i<=31;i++)
{
e[0][i][1]=0;
e[0][i][0]=0;
}
for(int i=1;i<=b;i++)
{
w^=c[i];
int hh=w;
for(int j=31;j>=0;j--)
{
e[i][j][1]=e[i-1][j][1];
e[i][j][0]=e[i-1][j][0];
if((hh>>j)&1==1)
{
e[i][j][1]++;
}
else
{
e[i][j][0]++;
}
}
}
int an=0;
for(int i=0;i<b;i++)
{
int v=0;
int w=0;
for(int j=31;j>=0;j--)
{
int h1=e[k[i]][j][1]-e[i][j][1];
int h2=e[k[i]][j][0]-e[i][j][0];
int mm=max(p[i]-2,(int)0);
int h3=e[i][j][1]-e[mm][j][1];
int h4=e[i][j][0]-e[mm][j][0];
int nn=pow(2,j);
v=(h1*h4+h2*h3)*nn%mod;
if(p[i]==1)
{
an=(an+((c[i+1]*h1)%mod*nn)%mod)%mod;
}
an=(an+(c[i+1]*v)%mod)%mod;
}
}
cout<<an<<endl;
}
}
“华为杯”杭州电子科技大学2023新生编程大赛--序列
最新推荐文章于 2024-11-13 08:00:44 发布
这篇文章介绍了如何使用C++编程语言,结合栈和动态规划算法,解决一个问题,即给定一系列整数,找到每个子序列中最大值的最小上升子序列长度。代码展示了从输入读取、处理到最终计算答案的过程。
摘要由CSDN通过智能技术生成