[JSOI2008]最大数

    xiaoxiao2022-06-30  71

    题目描述

    现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。 限制:L不超过当前数列的长度。 2、 插入操作。 语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。 限制:n是整数(可能为负数)并且在长整范围内。 注意:初始时数列是空的,没有一个数。

    输入格式: 第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足 (0 < D < 2,000,000,000) 接下来的M行,每行一个字符串,描述一个具体的操作。语法如上文所述。

    输出格式: 对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。

    输入样例:

    5 100 A 96 Q 1 A 97 Q 1 Q 2

    输出样例:

    96 93 96

    题解:简单线段树操作。

    #include<iostream> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #define INF 1999122700 #define LiangJiaJun main using namespace std; int tr[600004],t=0,n,mod; int M,up=1,last,l=0; void change(int pos,int x){ pos += up ; tr[pos] = x; pos >>= 1; while(pos > 0){ tr[pos] = max(tr[pos<<1],tr[pos<<1|1]); pos >>= 1; } } int query(int l,int r){ int ans = -INF; for(l=l+up-1,r=r+up+1;r-l>1;r>>=1,l>>=1){ if(~l&1) ans = max(ans , tr[l+1]); if(r&1) ans = max(ans , tr[r-1]); } return ans; } int LiangJiaJun(){ l=200004; scanf("%d%d",&M,&mod); while(up<l+2) up <<= 1; while(M--){ char ch[4]; scanf("%s%d",ch+1,&n); n%= mod; t %= mod; if(ch[1] == 'A'){ last++; change(last,(n+t)%mod); } if(ch[1] == 'Q'){ t = query(last-n+1,last); printf("%d\n",t); } } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1126099.html

    最新回复(0)