2016 大连网络赛 & hdu5875 (优先队列+离线)★

来源:互联网 发布:dota2能在mac上玩吗 编辑:程序博客网 时间:2024/06/05 11:49

题意:给你一个区间,求a_l%a_(l+1)%a_(l+2)%…%a_r 的值

分析:因为一个数连续模一个比他模数小的数不会模超过30次,所以预处理记录下每个位置的30次变化,离线输出就可。

具体做法就是优先队列保存一个结构体,里面记录模数以及原始位置,On扫一遍,对于每个位置,队首元素模数大于该位置数时,一直弹出,并压入更新后的模数及位置,同时记录下相关信息。

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <list>#include <queue>#include <map>#include <bitset>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-3#define maxn 300100#define MOD 1000000007struct node{    int x,pos;    bool operator < (const node & a)const    {        return x < a.x;    }}st,ans[maxn][35];int n;int a[maxn];int num[maxn];int main(){    int t,C = 1;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(int i = 1; i <= n; i++)        {            scanf("%d",&a[i]);            ans[i][0].pos = i;            ans[i][0].x = a[i];            num[i] = 1;        }        priority_queue<node> q;        for(int i = 1; i <= n; i++)        {            while(!q.empty() && a[i] <= q.top().x)            {                st = q.top();                q.pop();                int k = st.x % a[i];                //printf("%d %d %d %d\n",i,st.x,st.pos,k);                ans[st.pos][num[st.pos]].x = k;                ans[st.pos][num[st.pos]].pos = i;                num[st.pos]++;                st.x = k;                q.push(st);            }            st.x = a[i];            st.pos = i;            q.push(st);        }        int m;        scanf("%d",&m);        while(m--)        {            int x,y;            scanf("%d%d",&x,&y);            int flag = 0;            for(int i = 0; i < num[x]; i++)            {                if(ans[x][i].pos > y)                {                    printf("%d\n",ans[x][i-1].x);                    flag = 1;                    break;                }            }            //printf("%d\n",flag);            if(!flag)                printf("%d\n",ans[x][num[x]-1].x);        }    }    return 0;}


0 0