zoukankan      html  css  js  c++  java
  • HYSBZ 2957 分块

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2957

    题意:中文题面

    思路: 来自此博客

    首先明确问题,对于每栋楼房的斜率K=H/X,问题就是问有多少个楼房的K比前面所有楼房的K都要大。

    这题树套树当然可以,但是挺麻烦的,本渣觉得最简单就是分块……

    将N个楼房分成T块,不断维护每个块内楼房的可视序列,如一个块内楼房的高度分别为(3 1 4 2 6 7)那么这个块内楼房的可视序列就是(3 4 6 7)(注意不同的块内是不干扰的,如第一个块可视序列为(3 4 6),第二块的序列可以是(5 7 8))

    对于每个修改,我们只需对每个块内的楼房暴力维护可视序列就行了,O(N/T)

    对于每个询问,我们只需一个块一个块看,不断维护到目前为止的可视序列中K的最大值kmax(不在可视序列内的楼房的K值一定不大),那么对于查询每个块的时候,可以二分可视序列找到第一个大于kmax的位置,若没有则这个块的所有楼房都不可见,如果存在,那么这个位置后的此块中的可视序列楼房都能看见,那么就更新答案和kmax,不断往后做

    #define _CRT_SECURE_NO_DEPRECATE
    #include<stdio.h>  
    #include<string.h>  
    #include<cstring>
    #include<algorithm>  
    #include<queue>  
    #include<math.h>  
    #include<time.h>
    #include<vector>
    #include<iostream>
    #include<map>
    using namespace std;
    typedef long long int LL;
    const int MAXN = 100000 + 10;
    int belong[MAXN], block, num, L[MAXN], R[MAXN];
    int n, m;
    double h[MAXN];
    vector<double>Bh[MAXN];
    void build(){
        block = int(sqrt(n + 0.5));
        num = n / block; if (n%block){ num++; }
        for (int i = 1; i <= num; i++){
            Bh[i].clear();
            L[i] = (i - 1)*block + 1; R[i] = i*block;
        }
        R[num] = n;
        for (int i = 1; i <= n; i++){
            belong[i] = ((i - 1) / block) + 1;
        }
    }
    void modify(int pos, int val){
        Bh[belong[pos]].clear(); h[pos] = double(val) / pos;
        for (int i = L[belong[pos]]; i <= R[belong[pos]]; i++){
            if (i == L[belong[pos]]){
                Bh[belong[pos]].push_back(h[i]); continue;
            }
            if (h[i]>Bh[belong[pos]][Bh[belong[pos]].size() - 1]){
                Bh[belong[pos]].push_back(h[i]);
            }
        }
    }
    int query(){
        int ans = 0;
        double maxh = 0;
        for (int i = 1; i <= num; i++){
            int pos = upper_bound(Bh[i].begin(), Bh[i].end(), maxh) - Bh[i].begin();
            if (pos != Bh[i].size()){
                ans += Bh[i].size() - pos;
                maxh = Bh[i][Bh[i].size() - 1];
            }
        }
        return ans;
    }
    int main(){
    //#ifdef kirito
    //    freopen("in.txt", "r", stdin);
    //    freopen("out.txt", "w", stdout);
    //#endif
    //    int start = clock();
        while (~scanf("%d%d", &n, &m)){
            memset(h,0,sizeof(h));
            build();
            for (int i = 1; i <= m; i++){
                int pos, hei;
                scanf("%d%d", &pos, &hei); 
                modify(pos, hei);
                printf("%d
    ", query());
            }
        }
    //#ifdef LOCAL_TIME
    //    cout << "[Finished in " << clock() - start << " ms]" << endl;
    //#endif
        return 0;
    }
  • 相关阅读:
    ms sql server缓存清除与内存释放
    Linux学习23-Xftp上传文件显示乱码问题
    jmeter压测学习1-window环境准备与案例
    Linux学习22-文件上传与下载(rz,sz)
    httprunner学习16-locust性能测试
    httprunner学习15-运行用例命令行参数详解
    httprunner学习14-完整的项目结构设计
    httprunner学习13-环境变量.env
    httprunner学习12-hook 机制实现setup和teardown
    httprunner学习11-辅助函数debugtalk.py
  • 原文地址:https://www.cnblogs.com/kirito520/p/5945427.html
Copyright © 2011-2022 走看看