https://codeforces.com/gym/104385/problem/J
题意:
给一个正整数n,表示给出n个二次项系数为1的二次函数,第i个函数为y=(x-i)^2+bi,且<=1e5),然后给出正整数m(1<=m<=1e5),表示操作总数。
操作分为两种:
1)添加一个二次函数,给出参数a和b,表示y=(x-a)^2+b,注意a和b的范围为(1<=a,b<=n),【因为题目最终是要找最小值,所以当a相同的情况下,需要比较这里的b和原来的b哪个大,要替换成更小的那个b。
2)给出参数a,询问当x=a时,所有函数中,函数值最小的那个值是多少
题解:这里需要注意的点就是如何找到询问时 最小函数值需要在哪几个函数中进行查询。
以下为如何找到范围:
假设需要查询x=a时的最小值,那么假设y=(x-a)^2+1,令这个函数中y的值为1e5,那么则有(x-a)^2+1=100000,此时得到|x-a|约为317,所以查询的最大范围为[x-317,x+317],遍历这个范围中的函数,查找最小值即可找到答案。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],b[N],i=1;
int main(){
int n;
cin>>n;
for(;i<=n;i++){
cin>>b[i];
a[i]=i;
}
int m;
cin>>m;
while(m--){
int op;
cin>>op;
if(op==0){
int x,y;
cin>>x>>y;
if(b[x]>y)b[x]=y;
}
else if(op==1){
int x;
cin>>x;
int ans=0xffffff;
for(int j=(x-317>1?x-317:1);j<(n<x+318?n:x+318);j++){
if((x-a[j])*(x-a[j])+b[j]<ans)ans=(x-a[j])*(x-a[j])+b[j];
}
cout<<ans<<endl;
}
}
return 0;
}
提交,过辣!!!