codeforces 485D (RMQ)

来源:互联网 发布:淘宝宝贝经常修改价格 编辑:程序博客网 时间:2024/06/06 22:39

题意:n个数中找到 ai % aj的最大值。
这个RMQ做法是荷姐姐的,太强辣。


题解:先去重,然后将给的n个数插入到1-1000000这个序列中,用ST维护一个数列的最大值。那么对于每个数ai,枚举其倍数,那取到的最大值一定是(ai*j+1,ai*(j+1)-1)这个区间的最大值减去ai*j。
nlogn的预处理+O(1)的查询
然后不知道为什么我的程序挂了= =。只能交g++14过


#include <iostream>#include <algorithm>#include <queue>#include <stack>#include <cstdio>#include <string>#include <cstring>#include <vector>#include <set>#include <cmath>#define LL long long#define INF 0x3f3f3f3f#define MOD 1000000007const int maxn = 1000000 + 5;using namespace std;int st[maxn*2][25];int a[maxn];int main(){    int n;    scanf("%d",&n);    for(int i=0; i<n; i++){        scanf("%d",&a[i]);    }    sort(a,a+n);    n = unique(a,a+n) - a;    for(int i=0; i<n; i++)        st[a[i]][0] = a[i];    int top = a[n-1];    for(int j=1; (1<<j)<=top*2; j++)        for(int i=1; i+(1<<j)-1<=top*2; i++)            st[i][j] = max(st[i][j-1], st[i+(1<<(j-1))][j-1]);    int max_ = 0;    for(int i=0; i<n-1; i++){        if(a[i] == 1) continue;        int k = (int)(log((a[i]-1)*1.0)/log(2.0));        for(int j=a[i]; j<=top; j+=a[i]){            int ans = max(st[j+1][k],st[j+a[i]-(1<<k)][k]);            max_ = max(ans-j,max_);        }    }    printf("%d\n",max_);    return 0;}

顺带再复习一下RMQ

void init(){    for(int j=1; (1<<j)<=n; j++)        for(int i=0; i+(1<<j)-1<n; i++)            st[i][j] = max(st[i][j-1], st[i+(1<<(j-1))][j-1]);}int query(int l, int r){    int k = (int)(log((r-l+1)*1.0)/log(2.0));// 2^k <= (r-l+1)    return max(st[l][k], st[r-(1<<k)+1][k]);}