分组求对数和
思路:
两个小朋友手中数加和
>
=
k
>=k
>=k 即可
很容易想到遍历累加答案
当前遍历到的小朋友手中数字为
x
x
x,在之前的所以数中满足
y
>
=
k
−
x
y>=k-x
y>=k−x 都会产生贡献
统计满足条件的
y
y
y 看起来不是很好想
不等式变形
−
y
<
=
x
−
k
-y<=x-k
−y<=x−k
统计小于某个数的数的数量可以想到用树状数组
离散化处理读进来的数据就好了
记得给
p
o
s
+
1
pos+1
pos+1 保证
p
o
s
>
=
1
pos>=1
pos>=1
(好久没刷题了,打了下小白月赛感觉题目难度刚刚好,非常适合作为萌新的我
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 1e6 + 9;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
vector <int> d[maxn], v;
unordered_map <ll, ll> ma;
int c[maxn];
void update(int i, int k){
while(i <= maxn - 9) c[i] += k, i += i & (-i);
}
ll qry(int i){
ll ans = 0;while(i) ans += c[i], i -= i & (-i);
return ans;
}
void work()
{
cin >> n >> m;
for(int i = 1; i <= n; ++i){
int x, y;cin >> x;
while(x--){
cin >> y;
v.push_back(-y);
d[i].push_back(y);
}
}
sort(all(v));
v.erase(unique(all(v)), v.end());
ll ans = 0;
int cnt = v.size();
for(int i = 1; i <= n; ++i){
for(auto x : d[i]){
int pos = upper_bound(all(v), x - m) - v.begin() + 1;
(ans += qry(pos - 1)) %= mod;
}
for(auto x : d[i]){
int pos = lower_bound(all(v), -x) - v.begin() + 1;
update(pos, 1);
}
}
cout << ans;
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}