首页 > 其他分享 >P1198 [JSOI2008] 最大数

P1198 [JSOI2008] 最大数

时间:2024-02-16 15:13:06浏览次数:30  
标签:最大数 read ll JSOI2008 len P1198 fa while now

原题链接

题解1:单调栈+并查集?

单调栈特性:栈内元素大小和序号由栈底到栈顶具有单调性,本题大小单调减,序号单调增
维护:新元素入栈时,栈内剩余的所有小于该元素的元素出栈,并视新元素为集合首领,然后新元素入栈
查询:查询集合首领即可

code1

#define ll long long
#include<bits/stdc++.h>
using namespace std;

struct num {
    ll pos;
    ll val;
};

ll fa[200005] = {0};

ll finds(ll now) {
    return fa[now] = (now == fa[now] ? now : finds(fa[now]));
}

vector<ll> a;

inline void read(ll &x) {  
    x = 0;
    ll flag = 1;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') flag = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = (x << 3) + (x << 1) + (c ^ 48); 
        c = getchar();
    }
    x *= flag;
}

inline void write(ll x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int main() {
    ll m, d;
    read(m); read(d);

    for(ll i = 0; i < m; i++) fa[i] = i;

    ll t = 0, len = 0;
    stack<num> q;
    while(m--) {
        char op;
        ll n;
        scanf(" %c", &op);
        read(n);
        if(op == 'Q') {
            n = a.size() - n ;
            write(a[finds(n)]);
            putchar('\n');
            t = a[finds(n)];
        } else {
            a .push_back (n = (n + t) % d);
            while(!q.empty() && n >= q.top().val) {
                ll now = q.top().pos;
                fa[finds(now)] = a.size()-1;
                q.pop();
            }
            q.push({a.size()-1, n});
        }
    }
    return 0;
}

题解2

st表,不过是向左延申的st表

code

#define ll long long
#include<bits/stdc++.h>
using namespace std;

// Custom input and output functions
inline void read(ll &x) {  
    x = 0;
    ll flag = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') flag = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        x = (x << 3) + (x << 1) + (c ^ 48); 
        c = getchar();
    }
    x *= flag;
}

inline void write(ll x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

ll len = 0;
vector<vector<ll>> f(200005, vector<ll>(35, 0)); // Using vector for f
ll a[200005] = {0}; // Keeping a as an array since it's directly accessed by index and there's no mention of dynamic resizing

void change() {
    f[len][0] = a[len];
    for (ll i = 1; (1LL << i) <= len; i++) {
        f[len][i] = max(f[len][i - 1], f[len - (1LL << (i - 1))][i - 1]);
    }
}

int main() {
    ll n, d;
    read(n); // Using custom read function
    read(d); // Using custom read function
    ll t = 0;
    while (n--) {
        char op;
        cin >> op; // Keeping cin for char as it's simple and efficient
        ll x;
        read(x); // Using custom read function
        if (op == 'A') {
            a[++len] = (x + t) % d;
            change();
        } else {
            ll ans = 0;
            ll l = len - x + 1; // Ensuring correct value of l
            ll r = len;
            for (ll j = 31; j >= 0; j--) {
                if ((1LL << j) <= r - l + 1) { // Using 1LL to ensure long long calculation
                    ans = max(ans, f[r][j]);
                    r -= 1LL << j; // Adjusting r for the new position
                }
            }

            write(ans); // Using custom write function
            putchar('\n'); // To end the line after output
            t = ans;
        }
    }
    return 0;
}

标签:最大数,read,ll,JSOI2008,len,P1198,fa,while,now
From: https://www.cnblogs.com/pure4knowledge/p/18017168

相关文章

  • 求最大数字-od-python
    求最大数字题目给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除;删除某个重复的数字后,其它数字相对位置保持不变。如34533,数字3重复超过2次,需要删除其中一个3,删除第一个3后获得最大数值4533请返回经过删除操作......
  • P1197 [JSOI2008] 星球大战 题解
    P1197[JSOI2008]星球大战题解题目链接P1197[JSOI2008]星球大战简要思路看完题目的第一印象是——连通性。图论中判断连通性很容易想到并查集,但是并查集只支持合并和查询,并不支持删除,怎么办呢?考虑逆向思维,把删点的过程倒过来,看成加点和连边,那么此题就可以非常方便的用并......
  • Python 初学之华为OD机试题:求最大数字
    题目描述给定一个由纯数字组成以宇符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除;删除某个重复的数字后,其它数字相对位置保持不变。如"34533”,数字3重复超过2次,需要册除其中一个3,删除第一个3后获得最大数值"4533"。请返回经过删除操作后的最大的数值......
  • 【线段树入门】 P1198 最大数(区间最大值+无懒标记+末尾插入)
    1//笔记-自用2//#pragmaGCCoptimize("Ofast")3//#pragmaGCCoptimize("unroll-loops")4#define_CRT_SECURE_NO_WARNINGS5#defineAll(a)a.begin(),a.end()6#defineINF21474836477#include<bits/stdc++.h>8#include<nu......
  • C++前缀和算法应用:矩形区域不超过 K 的最大数值和
    题目给你一个mxn的矩阵matrix和一个整数k,找出并返回矩阵内部矩形区域的不超过k的最大数值和。题目数据保证总会存在一个数值和不超过k的矩形区域。示例1:输入:matrix=[[1,0,1],[0,-2,3]],k=2输出:2解释:蓝色边框圈出来的矩形区域[[0,1],[-2,3]]的数值和是......
  • 【算法题】6939. 数组中的最大数对和
    题目:给你一个下标从0开始的整数数组nums。请你从nums中找出和最大的一对数,且这两个数数位上最大的数字相等。返回最大和,如果不存在满足题意的数字对,返回-1。示例1:输入:nums=[51,71,17,24,42]输出:88解释:i=1和j=2,nums[i]和nums[j]数位上最大的数字相等,且这......
  • 可以被K整除连通块的最大数目
    给你一棵n个节点的无向树,节点编号为0到n-1。给你整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi有一条边同时给你一个下标从0开始长度为n的整数数组values,其中values[i]是第i个节点的值。再给你一个整数......
  • 6574: 最大数 线段树/单点加/求区间最大值
    描述 给定一个正整数数列a1,a2,a3,⋯,an,每一个数都在0~p–1之间。可以对这列数进行两种操作:添加操作:向序列后添加一个数,序列长度变成n+1;询问操作:询问这个序列中最后L个数中最大的数是多少。程序运行的最开始,整数序列为空。写一个程序,读入操作的序列,并输出询问操作的......
  • 贪心算法--拼接最大数字问题
    博客地址:https://www.cnblogs.com/zylyehuo/#-*-coding:utf-8-*-fromfunctoolsimportcmp_to_keydefxy_cmp(x,y):ifx+y<y+x:return1#表示x>yelifx+y>y+x:return-1#表示x<yelse:re......
  • QComboBox在ubuntu下不显示滚动条问题,下拉框出现位置不固定问题,设置显示最大数量不生
    这里的Ubuntu指的是银河麒麟,问题也是在麒麟下出现的。没有在Ubuntu试过是否有同样的问题。但是估计也差不多,毕竟国产系统跟Ubuntu本来就纠缠不清。用QT写了一个QComboBox,自定义了一些样式,在Windows下显示正常,但是在Ubuntu下不显示滚动条,下拉框位置根据当前选项变化而不是固定显示......