传送门: https://zoj.pintia.cn/problem-sets/91827364500/problems/91827370154
题意
对
于
两
个
长
度
相
同
的
区
间
a
和
b
,
如
果
∑
∣
a
i
−
b
i
∣
p
≤
V
,
则
成
这
两
个
区
间
为
g
o
o
d
区
间
.
对于两个长度相同的区间a和b,如果\sum|a_i-b_i|^p\leq V,则成这两个区间为good 区间.
对于两个长度相同的区间a和b,如果∑∣ai−bi∣p≤V,则成这两个区间为good区间.
给
出
两
个
长
度
相
同
的
数
列
,
在
这
两
个
数
列
中
分
别
选
择
两
个
区
间
,
存
在
多
少
个
g
o
o
d
区
间
。
给出两个长度相同的数列,在这两个数列中分别选择两个区间,存在多少个good区间。
给出两个长度相同的数列,在这两个数列中分别选择两个区间,存在多少个good区间。
思路
因
为
∑
∣
a
i
−
b
i
∣
p
有
绝
对
值
,
所
以
每
增
加
一
个
值
,
都
会
增
加
。
因为\sum|a_i-b_i|^p有绝对值,所以每增加一个值,都会增加。
因为∑∣ai−bi∣p有绝对值,所以每增加一个值,都会增加。
假
设
我
们
找
到
一
个
区
间
[
l
1
,
r
1
]
、
[
l
2
,
r
2
]
,
则
l
∈
[
l
1
,
r
1
]
,
l
′
∈
[
l
2
,
r
2
]
都
是
可
以
的
。
假设我们找到一个区间[l1,r1]、[l2,r2],则l\in [l1,r1],l'\in [l2,r2]都是可以的。
假设我们找到一个区间[l1,r1]、[l2,r2],则l∈[l1,r1],l′∈[l2,r2]都是可以的。
所 以 我 们 可 以 枚 举 区 间 起 点 , 然 后 计 算 终 点 , 最 后 维 护 区 间 , 更 新 和 统 计 答 案 即 可 。 所以我们可以枚举区间起点,然后计算终点,最后维护区间,更新和统计答案即可。 所以我们可以枚举区间起点,然后计算终点,最后维护区间,更新和统计答案即可。
Code
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
ll quick_pow(ll a, ll b) {
ll ans = 1;
while(b) {
if(b & 1) ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
void solve() {
int _; cin >> _;
while(_--) {
int n; ll V, p;
cin >> n >> V >> p;
vector<ll> x(n + 10);
vector<ll> y(n + 10);
for(int i = 1;i <= n; i++) cin >> x[i];
for(int i = 1;i <= n; i++) cin >> y[i];
ll ans = 0;
for(int len = 0;len <= n - 1; len++) { // 枚举指针距离
int l1 = 1, r1 = 1; // a
int l2 = 1 + len, r2 = 1 + len; // b
ll cnt = quick_pow(abs(x[l1] - y[l2]), p);
while(r2 <= n) { // 先让b动区间
if(cnt <= V) {
ans += r1 - l1 + 1;
r1++;
r2++;
cnt += quick_pow(abs(x[r1] - y[r2]), p);
}
else {
cnt -= quick_pow(abs(x[l1] - y[l2]), p);
l1++;
l2++;
if(l1 > r1) {
r1++;
r2++;
cnt += quick_pow(abs(x[r1] - y[r2]), p);
}
}
}
if(len == 0) continue;
l1 = 1 + len; r1 = 1 + len;
l2 = 1; r2 = 1;
cnt = quick_pow(abs(x[l1] - y[l2]), p);
while(r1 <= n) {
if(cnt <= V) {
ans += r2 - l2 + 1;
r1++;
r2++;
cnt += quick_pow(abs(x[r1] - y[r2]), p);
}
else {
cnt -= quick_pow(abs(x[l1] - y[l2]), p);
l1++;
l2++;
if(l2 > r2) {
r1++;
r2++;
cnt += quick_pow(abs(x[r1] - y[r2]), p);
}
}
}
}
cout << ans << endl;
}
}
signed main() {
solve();
}