前言
真简单,树状数组真简单,数论真简单 (我在口胡)
传送门 : https://atcoder.jp/contests/abc221/tasks/abc221_e
补题借鉴 : https://zhuanlan.zhihu.com/p/416410911
思路
题目需要求的是 满足 所有组数
A 1 ′ ≤ A k ′ A_{1}^{\prime} \leq A_{k}^{\prime} A1′≤Ak′
因此不难想象 如果我们排序之后 那么我们只需要枚举k
对于每一个k我们都求出所有可能 即 2 k 2^{k} 2k (二进制枚举中有用到)
C ( N , 0 ) + C ( N , 1 ) + C ( N , 2 ) + … + C ( N , N ) = 2 n C(N, 0)+C(N, 1)+C(N, 2)+\ldots+C(N, N)=2^{n} C(N,0)+C(N,1)+C(N,2)+…+C(N,N)=2n
因此 这题的 最终需要求的就是 : ∑ 1 ≤ i < j ≤ n 2 j − i − 1 [ a i ≤ a j ] \sum_{1 \leq i<j \leq n} 2^{j-i-1}\left[a_{i} \leq a_{j}\right] ∑1≤i<j≤n2j−i−1[ai≤aj]
-
对于我们在枚举 i 的时候 我们可以将公式拆分 ∑ i ≤ j ≤ n 2 j [ a i ≤ a j ] \sum_{i \leq j \leq n} 2^{j}\left[a_{i} \leq a_{j}\right] ∑i≤j≤n2j[ai≤aj]
然后我们在乘上 2 − i − 1 2^{-i-1} 2−i−1 又因为这题范围 2e5 因此我们需要在O(logn)的范围求出求和公式的值 -
我们可以用树状数组来处理 ∑ 2 j \sum 2^{j} ∑2j
-
最后我们只需要用 逆元 处理一下 乘上的 2 1 + i 2^{1+i} 21+i
优化 :
- 为了使 数组元素不超过n 因此我们需要对a数组进行离散化
- cc_hasptable 竟然比 hashmap还快一倍
- 这个树状数组这样写也太棒了吧
CODE
#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
using ll = long long;
const int N = 3e5+10;
const int mod = 998244353;
ll ans;
ll a[N],b[N];
struct node
{
int n;
ll T[N];
ll lowbit(ll x)
{
return x&(-x);
}
void modify(int pos,ll x)
{
for(int i=pos;i<=n;i+=lowbit(i))
T[i]+=x;
}
ll ask(int pos)
{
ll ans = 0 ;
for(int i = pos;i>=1;i-=lowbit(i))
ans+=T[i];
return ans;
}
ll query(int l,int r)
{
return (ask(r) - ask(l-1) + mod)%mod;
}
}T;
ll qmi(ll a,ll b)
{
ll res = 1;
a%=mod;
while(b>0){
if(b&1)
res = res*a%mod;
a = a*a % mod;
b>>=1;
}
return res;
}
/// 求b*x == 1 mod p
/// 费马小定理 求出 x == b^(p-2)
ll inv(ll x)
{
return qmi(x,mod - 2);
}
void solve()
{
int n;
cin>>n;
T.n = n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i] = a[i];
}
/*离散化*/
sort(b+1,b+1+n);
cc_hash_table<int,int> rk;
for(int i=1;i<=n;i++)
rk[b[i]] = i ;
for(int i=1;i<=n;i++)
T.modify(rk[a[i]],qmi(2,i));
for(int i=1;i<=n;i++)
{
T.modify(rk[a[i]], - qmi(2,i)+mod);
ans += inv(qmi(2,i+1)) * T.query(rk[a[i]],n);
ans%=mod;
}
cout<<ans%mod<<endl;
}
int main()
{
ios::sync_with_stdio(false);
solve();
return 0;
}
//1 2 3