Monocarp又在玩电脑游戏了。他是个巫师学徒,只会一个咒语。幸运的是,这个法术可以伤害怪物。他当前所在的关卡包含n个怪物。第i个在关卡开始后k秒出现,并拥有h个生命值点。作为一个附加约束,hi < ki对于所有1 <i< n。所有ki都是不同的。Monocarp可以在关卡开始后的正整数秒量的时刻施放法术:1,2,3,…法术伤害的计算方法如下。如果他在前一秒没有施法,伤害为1。否则,就让前一秒的损失消失吧。然后他可以选择伤害为æ + 1或1。法术使用法力值:施放伤害为A的法术需要x法力值。法力值不会回复。要杀死第i个怪物,Monocarp必须在怪物出现的那一刻施放至少h点伤害的法术,也就是ki注意,即使当前秒内没有怪物,单果也可以施放该法术。施法所需的法力值是所有施法法术的法力值之和。计算Monocarp杀死所有怪物所需的最小法力值。我们可以看到,在问题的限制条件下,玩家总是有可能杀死所有怪物。输入第一行包含一个整数t (1 < t < 104)——测试用例的数量。测试用例的第一行包含一个整数n (1 < n < 100)——关卡中怪物的数量。测试用例的第二行包含n个整数ki < k2 <…< kn (1 < ki < 10°)-从第i个怪物出现的开始的秒数。所有的k都是不同的,k是按递增顺序提供的。测试用例的第三行包含n个整数h1, h2,.., hn (1 < hi < k;< 10°)-第i个怪物的生命值。所有测试用例的n和不超过104。输出对于每个测试用例,打印一个整数——Monocarp杀死所有怪物所需的最小法力值。
Example
input
Copy
3
1
6
4
2
4 5
2 2
3
5 7 9
2 1 2
output
Copy
10 6 7
请注意在这个例子的第一个测试案例中,Monocarp可以在开始后3、4、5和6秒施放伤害分别为1、2、3和4的法术。6秒时造成的伤害为4,这确实大于或等于出现的怪物的生命值。在这个例子的第二个测试用例中,Monocarp可以在开始时施放3、4和5秒的法术,伤害分别为1、2和3。在这个例子的第三个测试案例中,Monocarp可以在开始时施放4,5,7,8,9秒的法术,伤害分别为1,2,1,1和2。
题解:
如果要让消耗最小,最好是法术伤害在ki时刚好等于hi,这样我们知道了每个区间最优应该从哪开始
ki - hi + 1 ~ ki
(好了,本题结束,开玩笑的)
我们相当于的到了n个区间,如果没有重复的直接计算即可,
那对于有重复的区间该怎么算呢
我们先对右边从小到大排序,得到的区间大概是这样的
如果区间直间有覆盖肯定是要从最左边的区间,计算的最右边的区间,这样才能满足后面被覆盖的区间,
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
using namespace std;
//#define int long long
const int N = 2e5 + 10;
typedef pair<int, int> PII;
typedef long long ll;
int k[N];
int h[N];
struct node
{
int l,r;
}a[N];
bool cmp(node a,node b)
{
return a.l < b.l;
}
void solve()
{
int n;
scanf("%d",&n);
ll ans = 0;
for(int i = 1;i <= n;i++)
{
scanf("%d",&k[i]);
}
for(int i = 1;i <= n;i++)
{
scanf("%d",&h[i]);
a[i].l = k[i] - h[i] + 1;
a[i].r = k[i];
}
sort(a + 1,a + 1 + n,cmp);
int s = a[1].l,e = a[1].r;
for(int i = 2;i <= n;i++)
{
if(a[i].l <= e)
{
s = min(s,a[i].l);
e = max(e,a[i].r);
}
else
{
ll len = e - s + 1;
ans += len*(len + 1)/2;
s = a[i].l;
e = a[i].r;
}
}
ll len = e - s + 1;
ans += len*(len + 1)/2;
cout << ans <<"\n";
}
//1 2 4
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
// cin >> t;
scanf("%d",&t);
while (t--)
{
solve();
}
}
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//0 1 1 1 1
//0 1 1 1 1