zoukankan      html  css  js  c++  java
  • POJ2886 Who Gets the Most Candies? 线段树 反素数

    题意:有一群小朋友围成一个环,编号1,2,3…N。每个人手上握着一个非0的数字,首先第K个人出列,然后看他手上的数字,假设为m,则从下一个开始第m个人出列,一直如此。并设i为小于等于N的最大反素数,问第i个出列的人得编号,i的约数个数。(设g(i)为i的约数的个数,若任意j<i,都有g(j)<g(i)则i为反素数)。

    首先要得到[0,N]的最大反素数(怎么得到下面再说),然后模拟出列操作,用线段树来优化使得每次出列在O(logN)时间内完成。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define maxn 100005
    
    int maxsub[maxn<<2], minsub[maxn<<2];
    int lmax[maxn<<2], rmax[maxn<<2];
    int lmin[maxn<<2], rmin[maxn<<2];
    int sum[maxn<<2];
    
    void PushUp(int rt) {
        int l = rt<<1;
        int r = l+1;
        sum[rt] = sum[l] + sum[r];
        maxsub[rt] = max(max(maxsub[l], maxsub[r]), rmax[l]+lmax[r]);
        minsub[rt] = min(min(minsub[l], minsub[r]), rmin[l]+lmin[r]);
        lmax[rt] = max(lmax[l], sum[l]+lmax[r]);
        rmax[rt] = max(rmax[r], sum[r]+rmax[l]);
        lmin[rt] = min(lmin[l], sum[l]+lmin[r]);
        rmin[rt] = min(rmin[r], sum[r]+rmin[l]);
    }
    
    void build(int l, int r, int rt) {
        if (l == r) {
           scanf("%d", &sum[rt]);
           minsub[rt] = lmax[rt] = rmax[rt] = lmin[rt] = rmin[rt] = maxsub[rt] = sum[rt];
           return;
        }
        int m = (l+r)>>1;
        build(l, m, rt<<1);
        build(m+1, r, rt<<1|1);
        PushUp(rt);
    }
    
    void update(int target, int val, int l, int r, int rt) {
        if (l == r) {
            sum[rt] = maxsub[rt] = minsub[rt] = val;
            lmax[rt] = rmax[rt] = lmin[rt] = rmin[rt] = val;
            return;
        }
        int m = (l+r)>>1;
        if (m >= target) update(target, val, l, m, rt<<1);
        else update(target, val, m+1, r, rt<<1|1);
        PushUp(rt);
    }
    
    int main()
    {
        int n, m, ans;
    
        scanf ("%d", &n);
        build(1, n, 1);
        scanf("%d", &m);
        while (m--) {
            int a, b;
            scanf ("%d%d", &a, &b);
            update(a, b, 1, n, 1);
            if (sum[1] == maxsub[1]) //序列全为非负数的时候
                ans = sum[1] - minsub[1];
            else ans = max(maxsub[1], sum[1]-minsub[1]);
            printf ("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    git stash 一个场景 mark
    sendBeacon 使用
    【踩坑笔记】layui之单选和复选框不显示
    wordpress后台管理超时没反应:load-scripts.php载入缓慢出错
    MySQL_Sql_打怪升级_进阶篇_测试: SQL随机生成测试数据
    MySQL_Sql_打怪升级_进阶篇_测试: 游标应用
    MySQL8.0新特性_01_JSON数据格式的支持
    MySQL_Sql_打怪升级_进阶篇_进阶19: 函数
    MySQL_Sql_打怪升级_进阶篇_进阶18: 存储过程
    MySQL_Sql_打怪升级_进阶篇_进阶17: 变量
  • 原文地址:https://www.cnblogs.com/0803yijia/p/3214758.html
Copyright © 2011-2022 走看看