终于仁慈了一天,可以好好写一天题解了(^_^)
T1.二次剩余(two)
题目大意:有(n)个二次函数(f_i(x)=(x-k_i)^2+h_i),有(m)个操作:
-
添加一个二次函数。
-
删除所有(f(x)le p)的二次函数。
另外,所有数均属于正整数!
有一个很暴力的做法,对于每一个对称轴开一个堆,然后每次比较时拿出(h)值最大的那个比较,并不断弹出堆顶。
这样的时间复杂度为(O(nmlog(n))),真TM还不如暴力 (虽然这个也是暴力),但这个算法有一个简单的优化:
对于每一个删除操作的(p),因为满足条件的函数((x-k_i)^2+h_ile p),又因为(h_i)为正整数,所以需要删掉的二次函数的对称轴只会在(x-sqrt p)和(x+sqrt p)之间,所以枚举范围就变成了根号级别,可以通过!
代码挺简单的,就不放了吧 (就是没打
T2.倍数区间(interval)
题目大意,求一个区间求最长子区间满足(exists a_i)使得(forall a_j)满足(a_i|a_j)。
最水的一个了吧,对于每一个(a_i)保存这个数左右两边最多连续多少个数可以整除它,然后比较答案就好了,但这样的时间复杂度是(O(n^2))的,可以加点优化,如果一个数(a_j)可以整除(a_i),那可以整除(a_j)的数也一定可以整除(a_i),所以一旦可以整除,则跳到(a_j)的最左可以整除的数,否则结束,确定区间。
题解太少了,放个代码吧。
#include<bits/stdc++.h>
#define re register
using namespace std;
const int N=500005;
int n,a[N],ans,que[N],len,l[N],r[N];
int main()
{
freopen("interval.in","r",stdin);
freopen("interval.out","w",stdout);
scanf("%d",&n);
for(re int i=1;i<=n;i++) scanf("%d",&a[i]),l[i]=r[i]=i;
for(re int i=1;i<=n;i++)
for(;l[i]>1&&a[l[i]-1]%a[i]==0;l[i]=max(l[l[i]-1],1));
for(re int i=n;i>0;i--)
for(;r[i]<n&&a[r[i]+1]%a[i]==0;r[i]=min(r[r[i]+1],n));
for(re int i=1;i<=n;i++)
{
if(r[i]-l[i]>ans) ans=r[i]-l[i],len=0;
if(r[i]-l[i]==ans) que[++len]=l[i];
}
re int mid=len;
sort(que+1,que+1+mid);
for(re int i=1;i<=mid;i++)
if(que[i]==que[i-1]) len--;
printf("%d %d
",len,ans);
for(re int i=1;i<=mid;i++)
if(que[i]!=que[i-1]) printf("%d ",que[i]);
return 0;
}
T3.飞翔的鸟(bird)
题目大意:这个游戏应该都玩过吧?一个高为(k),宽为(n)的地图,这题只有一个障碍随即出现在([2,n-1])之中,求小鸟从((1,k/2))飞到((n,k/2))的期望方案数对(10^9+7)取模的结果,小鸟只能飞向((x+1,y),(x+1,y+1),(x+1,y-1))三个方向。
也挺水的,(f[i][j])表示没有障碍到达这个点的方案数,用矩阵快速幂优化一下,就可以通过本题。
不愿写了,后续内容读者可以自行思考(逃