zoukankan      html  css  js  c++  java
  • LibreOJ #6282

    题目链接:#6282. 数列分块入门 6

    题目大意

    给出一个长为 (n) 的数列,以及 (n) 个操作,操作涉及单点插入,单点询问

    solution

    我们对于这两种操作:

    修改操作: 我们计入一下每个块的大小,然后找到所在的快, 每找到一个整块直接减去这个块的大小即可,然后当不能减了,就是所在块,直接暴力插入即可

    查询操作: 同修改操作,找到所在块,然后直接输出

    然后,我们喜闻乐见的 超时了

    我们发现如果一直插入一个块里,这个块会变得非常大,我们就会超时

    我们有两种应对措施:

    1. 我们可以每多 (sqrt(n)) 的时候,进行暴力重构

    2. 我们也可以在某个块达到一定大小时,暴力重构

    暴力重构的时间复杂度是正确的,自己可以证明一下本人不想写了

    Code:

    /**
    *    Author: Alieme
    *    Data: 2020.9.8
    *    Problem: LibreOJ #6282
    *    Time: O()
    */
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    #define ll long long
    #define rr register
    
    #define inf 1e9
    #define MAXN 200010
    
    using namespace std;
    
    inline void read(int &T) {
    	T = 0;
    	int f = 0;
    	char ch = getchar();
    	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
    	while (isdigit(ch)) T = T * 10 + (ch ^ 48), ch = getchar();
    	if (f) T = -T;
    }
    
    void print(int x) {
    	if (x < 0) putchar('-'), x = -x;
    	if (x > 9) print(x / 10);
    	putchar(x % 10 + 48);
    }
    
    int n, len, sum, tot;
    
    int siz[MAXN], id[MAXN], a[MAXN];
    
    int v[600][MAXN];
    
    inline void build() {
    	sum = 0;
    	int cnt = 0;
    	for (rr int i = 1; i <= id[tot]; i++) 
    		for (rr int j = 1; j <= siz[i]; j++)
    			a[++cnt] = v[i][j];
    	tot = cnt;
    	memset(siz, 0, sizeof siz);
    	for (rr int i = 1; i <= tot; i++) 
    		id[i] = (i - 1) / len + 1, v[id[i]][++siz[id[i]]] = a[i];
    }
    
    inline void add(int l, int r) {
    	int i;
    	sum++;
    	for (i = 1; i <= id[tot]; i++) 
    		if (l - siz[i] > 0) l -= siz[i]; 
    		else break;
    	for (rr int k = siz[i] + 1; k >= l; k--) v[i][k + 1] = v[i][k];
    	v[i][l] = r;
    	siz[i]++;
    	if (sum == len) build();
    }
    
    inline int query(int r) {
    	int i;
    	for (i = 1; i <= id[tot]; i++)
    		if (r - siz[i] > 0) r -= siz[i];
    		else break;
    	return v[i][r];
    }
    
    signed main() {
    	// freopen("a1.in", "r", stdin);
    	// freopen("a.out", "w", stdout);
    	read(n);
    	len = sqrt(n);
    	for (rr int i = 1; i <= n; i++) read(a[i]), id[i] = (i - 1) / len + 1, v[id[i]][++siz[id[i]]] = a[i];
    	tot = n;
    	for (rr int i = 1; i <= n; i++) {
    		int opt, l, r, c;
    		read(opt), read(l), read(r), read(c);
    		if (opt == 0) add(l, r);
    		if (opt == 1) cout << query(r) << "
    ";
    	}
    }
    
  • 相关阅读:
    随机森林算法参数调优
    BAYES和朴素BAYES
    阿里云 金融接口 token PHP
    PHP mysql 按时间分组 表格table 跨度 rowspan
    MySql按周,按月,按日分组统计数据
    PHP 获取今日、昨日、本周、上周、本月的等等常用的起始时间戳和结束时间戳的时间处理类
    thinkphp5 tp5 会话控制 session 登录 退出 检查检验登录 判断是否应该跳转到上次url
    微信 模板消息
    php 腾讯 地图 api 计算 坐标 两点 距离 微信 网页 WebService API
    php添加http头禁止浏览器缓存
  • 原文地址:https://www.cnblogs.com/lieberdq/p/13641831.html
Copyright © 2011-2022 走看看