4320: ShangHai2006 Homework

4320: ShangHai2006 Homework

链接

分析:

  分块。对权值模数进行分块,模数小于$\sqrt V$的($V$为权值上界),暴力处理。

  模数大于$\sqrt V$的,设模数是k,枚举k的倍数,然后查询大于[k,2k]之间的最小的数x,这个区间的mod k最小的数就是x-k。k的倍数共有$\sqrt V$个,每次查询,再对权值进行分块,并维护后缀最小值,做到$O(1)$查询。复杂度$O(n \sqrt V)$

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f;
}

const int N = 300000, M = 550, INF = 1e9;
int bel[N + 5], tag[N + 5], f[N + 5], pt[N + 5];

void add(int x) {
    for (int i = 1; i <= M; ++i) f[i] = min(f[i], x % i);
    tag[bel[x]] = min(tag[bel[x]], x);
    pt[x] = min(pt[x], x);
    for (int i = x - 1, lim = (bel[x] - 1) * M; i >= lim; --i) pt[i] = min(pt[i], pt[i + 1]);
    for (int i = bel[x] - 1; i; --i) tag[i] = min(tag[i], tag[i + 1]);
}
int query(int x) {
    return min(pt[x], tag[bel[x] + 1]);
}
int Ask(int x) {
    if (x <= M) return f[x];
    int ans = query(1) % x;
    for (int i = x; i <= N; i += x) {
        int t = query(i) - i;
        if (t < x) ans = min(ans, t);
    }
    return ans;
}
int main() {
    memset(f, 0x3f, sizeof(f));
    memset(tag, 0x3f, sizeof(tag));
    memset(pt, 0x3f, sizeof(pt));
    int n = read();
    for (int i = 1; i <= N; ++i) bel[i] = (i - 1) / M + 1;
    char opt[10];
    for (int i = 1; i <= n; ++i) {
        scanf("%s", opt); int x = read();
        if (opt[0] == ‘A‘) add(x);
        else printf("%d\n", Ask(x));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/mjtcn/p/10294982.html

时间: 2025-01-10 17:32:20

4320: ShangHai2006 Homework的相关文章

BZOJ 4320 ShangHai2006 Homework

题意: 给出N(<=1e5)个操作,操作分为两种,①在集合中添加一个数x,②问这个集合中mod x 的最小值是多少.(x <= 3e5) 题解: 0.首先我们发现log家族中有算法满足这道题目,那么采用分块的思想. 1.那么对于小于根号下MAX(x)的询问,直接暴力维护答案,对于大于根号MAX(x)的询问,只需要找到第一个大于等于K * x 的值是多少. 2.那么现在问题是维护第一个大于等于K * x 的值是多少,现在有两种选择,①用STL中的<set> 中的 lower_boun

bzoj 4320: ShangHai2006 Homework【分块】

按根号300000=m分情况讨论 查询是,当x小于等于m,那么可以暴力记录直接出解:否则,用分块维护区间值,查询的时候以x为步长跳根号m次取最小值即可 还有一种并查集方法,来自https://www.cnblogs.com/CQzhangyu/p/7088337.html #include<iostream> #include<cstdio> using namespace std; const int N=300010,M=550; int n=300000,m=n/M,q,i,

【BZOJ4320】ShangHai2006 Homework 分段+并查集

[BZOJ4320]ShangHai2006 Homework Description 1:在人物集合 S 中加入一个新的程序员,其代号为 X,保证 X 在当前集合中不存在. 2:在当前的人物集合中询问程序员的mod Y 最小的值. (为什么统计这个?因为拯救过世界的人太多了,只能取模) Input 第一行为用空格隔开的一个个正整数 N. 接下来有 N 行,若该行第一个字符为“A” ,则表示操作 1:若为“B”,表示操作 2: 其中 对于 100%的数据:N≤100000, 1≤X,Y≤3000

BZOJ4320 ShangHai2006 Homework

Description 1:在人物集合 S 中加入一个新的程序员,其代号为 X,保证 X 在当前集合中不存在. 2:在当前的人物集合中询问程序员的mod Y 最小的值. (为什么统计这个?因为拯救 过世界的人太多了,只能取模) Input 第一行为用空格隔开的一个个正整数 N. 接下来有 N 行,若该行第一个字符为“A” ,则表示操作 1:若为“B”,表示操作 2: 其中 对于 100%的数据:N≤100000, 1≤X,Y≤300000,保证第二行为操作 1. Output 对于操作 2,每行

【bzoj4320】ShangHai2006 Homework

若Y小于等于sqrt(300000),暴力,对所有的插入的数都更新mn[i]. 若Y大于sqrt(300000),枚举kY,用并查集维护>=i的第一个数,这样只支持删除操作是O(1),然后倒着枚举一边,删除一个数x那么就fa[x]=fa[x+1] #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #inclu

论逗逼的自我修养——乱做计划

我看IOI各种鬼畜题目做做,深知自身姿势水平不足无以抗衡就乱搞一些傻逼题做做. 现在已经跪了0道 [BZOJ3749][POI2015]?asuchy 枚举第一个狗粮被谁吃了,后面的dp就可以了,记录下dp的路径,最后时候验证与假设是否矛盾即可. [BZOJ3750][POI2015]Piecz?? 暴力枚举左上角判断一下. [BZOJ3733][Pa2013]lloczyn 一开始用一个诡异的姿势WA了之后很久没能想出多项式做法,膜了一发鏼之后发现是大(d)法(f)师(s).我们从小到大枚举不

待 题表

题表 达哥终极杂题表Bzoj2839 hdu6021 Codeforces 804DBzoj2248 hdu5575 Codeforces 786CBzoj2013 bzoj2676 Codeforces 803CBzoj2386 bzoj3782 Codeforces 813DBzoj2699 cogs1667 Codeforces 814DBzoj4798 bzoj2064 Codeforces 814EBzoj4639 bzoj3505 Codeforces 815ABzoj4417 bz

BZOJ 4320 Homework

首先要想清楚一定是按根号分块.对于<根号的直接记录.>根号的怎么办呢? 设查询的是%y. 那么我们只要找一个0,y,2y,3y.....的lowerbound就好了.而这是根号的.到此总复杂度n√nlogn,无法通过此题. 怎么办呢?可以考虑离线.我们维护并查集,每个点的祖先是在数轴上它的右边第一个出现的数. 那么倒着做就是删数,就可以合并两个集合,就好了.复杂度n√nα(n). #include<iostream> #include<cstdio> #include&

HDU 1789 Doing Homework again(贪心)

Doing Homework again Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadlin