zoukankan      html  css  js  c++  java
  • luogu1198 JSOI2008 最大数

    题目

    题目描述
    现在请求你维护一个数列,要求提供以下两种操作:

    1、 查询操作。

    语法:Q L

    功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。

    限制:L不超过当前数列的长度。(L>=0)

    2、 插入操作。

    语法:A n

    功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。

    限制:n是整数(可能为负数)并且在长整范围内。

    注意:初始时数列是空的,没有一个数。

    输入输出格式
    输入格式:
    第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0<D<2,000,000,000)

    接下来的M行,每行一个字符串,描述一个具体的操作。语法如上文所述。

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

    输入输出样例
    输入样例#1: 复制
    5 100
    A 96
    Q 1
    A 97
    Q 1
    Q 2
    输出样例#1: 复制
    96
    93
    96
    说明
    [JSOI2008]

    本题数据已加强

    分析

    做法挺多的:线段树,单调栈,分块,ST表

    我只用了线段树与单调栈两种^_^

    (才不是懒)

    代码

    线段树做法:

      1 /*
      2 ID: Mandy
      3 language:c++
      4 problem:luogu 1198
      5 */
      6 #include<bits/stdc++.h>
      7 
      8 #define N 1002
      9 #define M 200005
     10 #define maxl 8446744073709551616
     11 #define Max(x,y) (x)>(y)?(x):(y)
     12 #define Min(x,y) (x)<(y)?(x):(y)
     13 #define up(i,l,r) for(int i=l;i<=r;++i)
     14 #define down(i,l,r) for(int i=r;i>=l;--i)
     15 
     16 using namespace std;
     17 
     18 const int maxm=262143;
     19 long long m,mod,lenth,maxn[M<<2],last,dep=0;
     20 bool vis[M<<2];
     21 
     22 template<class T>inline void read(T &x)
     23 {
     24     x=0;bool flag=0;char ch=getchar();
     25     while(ch<'0'||ch>'9') flag|=(ch=='-'),ch=getchar();
     26     while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
     27     if(flag) x=-x;
     28 }
     29 
     30 template<class T>void putch(const T x)
     31 {
     32     if(x>9) putch(x/10);
     33     putchar(x%10|48);
     34 }
     35 
     36 template<class T>inline void put(const T x)
     37 {
     38     if(x<0) putchar('-'),putch(-x);
     39     else putch(x);
     40 }
     41 
     42 void docu()
     43 {
     44     freopen("1198.in","r",stdin);
     45     freopen("1198.out","w",stdout); 
     46 } 
     47 
     48 void readdata()
     49 {
     50     read(m);
     51     read(mod);
     52 }
     53 
     54 long long ask(int k,int l,int r,int x,int y)
     55 {
     56     if(l>y||r<x) return -maxl; 
     57     if(l>=x&&r<=y) return maxn[k];
     58     else
     59     {
     60         int mid=(l+r)>>1;
     61         long long ans=ask(k<<1,l,mid,x,y);
     62         long long ans1=ask((k<<1)+1,mid+1,r,x,y);
     63         if(ans<ans1) ans=ans1;
     64         return ans;
     65     }
     66 }
     67 
     68 void modify(int pos,long long val)
     69 {
     70     int l=1,r=200000,k=1;
     71     
     72     while(l!=r)
     73     {
     74         int mid=(l+r)>>1;
     75         if(pos<=mid) r=mid,k<<=1;
     76         else l=mid+1,k=(k<<1)+1;
     77     }
     78     
     79     maxn[k]=val;
     80     k>>=1;
     81     while(k>=1) 
     82     {
     83         maxn[k]=max(maxn[k<<1],maxn[(k<<1)+1]);
     84         k>>=1;
     85     }
     86 }
     87 
     88 void work()
     89 {
     90     up(i,1,m)
     91     {
     92         char judge=getchar();
     93         while(judge!='A'&&judge!='Q') judge=getchar();
     94         long long x; read(x);
     95         if(judge=='Q')
     96         {
     97             if(lenth==0)
     98             {
     99                 putchar('0');
    100                 putchar('
    ');
    101                 continue;
    102             }
    103             dep=0;
    104             last=ask(1,1,200000,lenth-(x-1),lenth)%mod;
    105             printf("%lld
    ",last);
    106         }
    107         else
    108         {
    109             ++lenth;
    110             x=(x+last)%mod;
    111             modify(lenth,x);
    112         }
    113         
    114     }
    115 }
    116 
    117 int main()
    118 {
    119     //docu();
    120     readdata();
    121     work();
    122     return 0;
    123 }
    View Code

    单调栈做法:

     1 /*************************
     2 User:Mandy.H.Y
     3 Language:c++
     4 Problem:luogu1198 JSOI2008 最大数
     5 Algorithm:
     6 *************************/
     7 #include<bits/stdc++.h>
     8 #define Max(x,y) ((x)>(y)?(x):(y))
     9 
    10 using namespace std;
    11 
    12 const int maxm = 2e5 + 5;
    13 
    14 int m,d,tp,cnt;
    15 int s1[maxm],s2[maxm];
    16 //s1 中单调递减,进了大数后,前面的小数就没用了
    17 //s2 中存下相应的位置 
    18 char *TT,*mo,but[(1 << 15) + 2];
    19 #define getchar() ((TT == mo && (mo = ((TT = but) + fread(but,1,1 << 15,stdin)),TT == mo)) ? -1 : *TT++)
    20 template<class T>inline void read(T &x){
    21     x = 0;bool flag = 0;char ch = getchar();
    22     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
    23     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    24     if(flag) x = -x;
    25 }
    26 
    27 template<class T>void putch(const T x){
    28     if(x > 9) putch(x / 10);
    29     putchar(x % 10 | 48);
    30 }
    31 
    32 template<class T>void put(const T x){
    33     if(x < 0) putchar('-'),putch(-x);
    34     else putch(x);
    35 }
    36 
    37 void file(){
    38     freopen("1198.in","r",stdin);
    39 //    freopen("1198.out","w",stdout);
    40 }
    41 
    42 void readdata(){
    43     read(m);read(d);
    44 }
    45 
    46 int erfen(int x){
    47     int l = 0,r = tp - 1;
    48     while(l < r){
    49         int mid = (l + r) >> 1;
    50         if(s2[mid] < x) l = mid + 1;//找第1个大于等于x的位置 
    51         else r = mid;
    52     }
    53     return s1[l];
    54 }
    55 
    56 void work(){
    57     int t = 0;
    58     for(int i = 1;i <= m; ++ i){
    59         char c = getchar();
    60         int l,n;
    61         while(c != 'Q' && c != 'A') c = getchar();
    62         if(c == 'Q'){
    63             read(l);
    64             int ans = erfen(cnt - l + 1);//找位置 
    65             put(ans);
    66             puts("");
    67             t = ans;
    68         } else {
    69             ++cnt;
    70             read(n);
    71             n = ((long long)n + t) % d;
    72             while(tp > 0 && s1[tp - 1] <= n) tp--;
    73             s1[tp++] = n;
    74             s2[tp - 1] = cnt; 
    75         }
    76     }
    77 }
    78 
    79 int main(){
    80 //    file();
    81     readdata();
    82     work();
    83     return 0;
    84 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    Linked list
    mysql(1)

    mysql 1130 问题
    POST乱码
    GET乱码(2)
    GET乱码
    P65——练习题2.31
    2.1.9 C语言中的移位运算
    2.1中所想的问题:指针的类型有什么作用?
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11366528.html
Copyright © 2011-2022 走看看