zoukankan      html  css  js  c++  java
  • [单调栈] 2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest-Maximum Element In A Stack

    题目:https://codeforces.com/gym/102222/problem/A

    Maximum Element In A Stack

    time limit per test
    10.0 s
    memory limit per test
    256 MB
    input
    standard input
    output
    standard output

    As an ACM-ICPC newbie, Aishah is learning data structures in computer science. She has already known that a stack, as a data structure, can serve as a collection of elements with two operations:

    • push, which inserts an element to the collection, and
    • pop, which deletes the most recently inserted element that has not yet deleted.

    Now, Aishah hopes a more intelligent stack which can display the maximum element in the stack dynamically. Please write a program to help her accomplish this goal and go through a test with several operations.

    Aishah assumes that the stack is empty at first. Your program will output the maximum element in the stack after each operation. If at some point the stack is empty, the output should be zero.

    Input

    The input contains several test cases, and the first line is a positive integer T

    indicating the number of test cases which is up to 50

    .

    To avoid unconcerned time consuming in reading data, each test case is described by seven integers n (1n5×106)

    , p, q, m (1p,q,m109), SA, SB and SC (104SA,SB,SC106). The integer n

    is the number of operations, and your program is asked to generate all operations by using the following code in C++.

    int n, p, q, m; unsigned int SA, SB, SC; unsigned int rng61(){ SA ^= SA « 16; SA ^= SA » 5; SA ^= SA « 1; unsigned int t = SA; SA = SB; SB = SC; SC ^= t ^ SA; return SC; } void gen(){ scanf(" for(int i = 1; i <= n; i++){ if(rng61() PUSH(rng61() else POP(); } }

    The procedure PUSH(v) used in the code inserts a new element with value v

    into the stack and the procedure POP() pops the topmost element in the stack or does nothing if the stack is empty.

    Output

    For each test case, output a line containing Case #x: y, where x is the test case number starting from 1

    , and y is equal to i=1n(iai) where

    means bitwise xor.

    Example
    Input
    Copy
    2
    4 1 1 4 23333 66666 233333
    4 2 1 4 23333 66666 233333
    Output
    Copy
    Case #1: 19
    Case #2: 1
    Note

    The first test case in the sample input has 4

    operations:

    • POP();
    • POP();
    • PUSH(1);
    • PUSH(4).

    The second test case also has 4

    operations:

    • PUSH(2);
    • POP();
    • PUSH(1);
    • POP().

    题意:

    给你一个栈和一个叫rng61的算法,当符合条件就加入一些内容到栈中,并在每次操作后记录当前栈中最大值ai,最后输出答案1到n的异或和i*ai

    思路:

    rng61是优化不了了,但我们可以在找栈中最大值时优化,如果是要询问栈中最大值,那么如果当前加入的元素小于以前记录的最大值,那么这个信息是没有记录的必要的,
    所以可以用一个单调不减的单调栈存每个状态的最大值,另一个普通栈存操作的原始序列,如果要往普通栈中推入元素,则如果这个元素大于等于单调栈的栈顶则加入单调栈,
    如果在普通栈进行pop操作,则看当前pop的元素是否>=单调栈的栈顶,如果是就把单调栈的栈顶pop(因为我们在单调栈中存的是单调不减的元素,所以如果碰到普通栈pop的元素大于等于单调栈栈顶元素,则这个元素必定是加入过单调栈的),
    如果普通栈为空或单调栈为空,则清空单调栈并向单调栈中推入一个0元素
    然后每次操作的普通栈中的最大值就是单调栈的栈顶

    注意:

    1.栈不为空时才能进行pop操作(如果是数组模拟则tp--后如果tp<0则需要让tp=0)

    2.ans要用long long存,这次比赛是算法是写正确了,但实现时用了unsigned int,一直卡在最后的数据,以后像ans,求和,求积之类的果断用long long来存(防溢出用long long)

     1 #include<bits/stdc++.h>
     2 typedef long long ll;
     3 using namespace std;
     4 int n,p,q,m;bool adf;
     5 long long ans;
     6 unsigned int SA,SB,SC;
     7 long long last,sttp,dsttp;
     8 stack<long long> st,dst;
     9 unsigned int rng61(){
    10     SA^=SA<<16;
    11     SA^=SA>>5;
    12     SA^=SA<<1;
    13     unsigned int t=SA;SA=SB;
    14     SB=SC;
    15     SC^=t^SA;
    16     return SC;
    17 }
    18 void gen(){
    19     scanf("%d%d%d%d%u%u%u",&n,&p,&q,&m,&SA,&SB,&SC);
    20     while(st.size())st.pop();while(dst.size())dst.pop();
    21     ans=0;
    22     for(unsigned int i=1;i<=n;i++){
    23         adf=1;
    24         if(dst.empty())dst.push(0);
    25         if(rng61()%(p+q)<p)st.push(rng61()%m+1);
    26         else if(st.size()) last=st.top(),st.pop(),adf=0;
    27         if(st.empty()){
    28             ans^=i*0;
    29             while(dst.size())dst.pop();
    30             dst.push(0);
    31         }
    32         else {
    33             sttp=st.top(),dsttp=dst.top();
    34             if(adf){
    35                 if(sttp>=dsttp)dst.push(sttp);
    36             }
    37             else {
    38                 if(last>=dsttp&&dst.size())dst.pop();
    39             }
    40             if(dst.empty())dst.push(0);
    41             ans^=i*dst.top();
    42         }
    43     }
    44 }
    45 int main(){
    46     int T,cas=1;
    47     scanf("%d",&T);
    48     while(T--){
    49         gen();
    50         printf("Case #%d: %lld
    ",cas++,ans);
    51     }
    52 }
    53 /**
    54 给你一个栈和一个叫rng61的算法,当符合条件就加入一些内容到栈中,并在每次操作后记录当前栈中最大值ai,最后输出答案1到n的异或和i*ai
    55 rng61是优化不了了,但我们可以在找栈中最大值时优化,如果是要询问栈中最大值,那么如果当前加入的元素小于以前记录的最大值,那么这个信息是没有记录的必要的,
    56 所以可以用一个单调不减的单调栈存每个状态的最大值,另一个普通栈存操作的原始序列,如果要往普通栈中推入元素,则如果这个元素大于等于单调栈的栈顶则加入单调栈,
    57 如果在普通栈进行pop操作,则看当前pop的元素是否>=单调栈的栈顶,如果是就把单调栈的栈顶pop(因为我们在单调栈中存的是单调不减的元素,所以如果碰到普通栈pop的元素大于等于单调栈栈顶元素,则这个元素必定是加入过单调栈的),
    58 如果普通栈为空或单调栈为空,则清空单调栈并向单调栈中推入一个0元素
    59 然后每次操作的普通栈中的最大值就是单调栈的栈顶
    60 注意栈不为空时才能进行pop操作(如果是数组模拟则tp--后如果tp<0则需要让tp=0),ans要用long long存,这次比赛是算法是写正确了,但实现时用了unsigned int,一直卡在最后的数据,以后像ans,求和,求积之类的果断用long long来存
    61 **/

     

    题外话:2019银川网络赛竟然用原题,变成了大学生程序重构大赛,比搜索比手速,前有tourist5小时AKWF,今有北师大6分钟AK网络赛(写完C后被队友告知北师大已经只差1题就AK了)

  • 相关阅读:
    java 封装练习题3
    java 封装练习题2
    java 封装练习题1
    java 面向对象练习题6
    java 面向对象练习题5
    java 面向对象练习题4
    java 练习 计算5的阶乘 5!的结果是?
    java 练习 题目四:控制台输出九九乘法表
    java 练习 题目三:这是经典的"百马百担"问题,有一百匹马,驮一百担货,大马驮3担,中马驮2担,两只小马驮1担,问有大,中,小马各几匹?
    java 练习 题目二:我国古代数学家张邱建在《算经》中出了一道“百钱买百鸡”的问题,题意是这样的:5文钱可以买一只公鸡,3文钱可以买一只母鸡,1文钱可以买3只雏鸡。现在用100文钱买100只鸡,那么各有公鸡、母鸡、雏鸡多少只?请编写程序实现。
  • 原文地址:https://www.cnblogs.com/Railgun000/p/11441674.html
Copyright © 2011-2022 走看看