【[Ynoi2018]五彩斑斓的世界】

分块毒瘤题。如果真的想好好练习思维以及代码的话就请不要使用\(\text{WC}\)讲过的黑科技指令集。

正文部分:

由乃题必定分块。

我们可以将同一个块内值相同的用并查集维护起来,因为如果是一个块内相同的值打标机怎么改都一样。

接着谈修改,我们设块内最大值为\(\text{mx}\),修改的值为\(\text{v}\)

如果\(v*2>mx\)的话就改大于\(\text{v}\)的,否则就改小于\(\text{v}\)的

原理是因为如果大于\(\text{v}\)的比较少的话改大的,否则改小的。

改小的时候我们可以把小的数全部加上\(\text{v}\),然后对这个块打上一个减标记。

My Code:

// luogu-judger-enable-o2
#pragma GCC optimize("Ofast,fast-math")
#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
#define _max(x,y) (x > y ? x : y)
using namespace std;
static char buf[100000],*p1,*p2;
static char pbuf[1000000],*pp(pbuf),st[15];
inline int read() {
    register int res(0);register char c(gc);
    while(c < ‘0‘ || c > ‘9‘) c = gc;
    while(c >= ‘0‘ && c <= ‘9‘) res = res * 10 + c - 48,c = gc;
    return res;
}
inline void print(register int v) {
    if(!v) *pp++ = 48;
    else {
        register int tp(0);
        while(v) st[++tp] = v % 10 + 48,v /= 10;
        while(tp) *pp++ = st[tp--];
    }
    *pp++ = ‘\n‘;
}
int fa[100010],a[100010],bel[100010];
int bl[320],br[320],Max[320],tag[320];
int root[320][100010];
unsigned short cnt[100010];
int n,m,i,j,k,bls;
int getf(int o) {
    if(o == fa[o]) return o;
    else return fa[o] = getf(fa[o]);
}
inline void build(int num) {
    Max[num] = 0;
    for(register int i = bl[num];i <= br[num];++i) {
        if(!root[num][a[i]]) {
            root[num][a[i]] = i;
            fa[i] = i;
            cnt[root[num][a[i]]] = 1;
        } else {
            fa[i] = root[num][a[i]];
            cnt[root[num][a[i]]]++;
        }
        Max[num] = _max(Max[num],a[i]);
    }
    return;
}
inline void pd(int num) {
    for(register int i = bl[num];i <= br[num];++i) {
        a[i] = a[getf(i)];
        cnt[root[num][a[i]]] = 0;root[num][a[i]] = 0;
    }
    for(register int i = bl[num];i <= br[num];++i) {
        a[i] -= tag[num];fa[i] = 0;
    }
    tag[num] = 0;
    return;
}
inline void change1(int l,int r,int x) {
    for(register int i = bel[l];i <= bel[r];++i) pd(i);
    for(register int i = l;i <= r;++i) {
        if(a[i] > x) a[i] -= x;
    }
    for(register int i = bel[l];i <= bel[r];++i) build(i);
    return;
}
inline void rpl(int x,int y,int z) {
    if(!root[x][y]) return;
    if(!root[x][z]) {
        root[x][z] = root[x][y];
        cnt[root[x][z]] = cnt[root[x][y]];
        a[root[x][y]] = z;
    } else {
        fa[root[x][y]] = root[x][z];
        cnt[root[x][z]] += cnt[root[x][y]];
    }
    root[x][y] = 0;
    cnt[root[x][y]] = 0;
    return;
}
inline void change2(int num,int val) {
    if(val >= Max[num] - tag[num]) return;
    if(val << 1 > Max[num] - tag[num]) {
        for(register int i = tag[num] + val + 1;i <= Max[num];++i) rpl(num,i,i - val);
     //   Max[num] -= val;Chkmax(Max[num],val + tag[num]);
        Max[num] = _max(Max[num] - val,val + tag[num]);
    } else {
        for(register int i = tag[num] + 1;i <= tag[num] + val;++i) rpl(num,i,i + val);
        tag[num] += val;
    }
    return;
}
inline void modify(int l,int r,int x) {
    if(bel[l] + 1 >= bel[r]) {
        change1(l,r,x);
        return;
    }
    change1(l,br[bel[l]],x);change1(bl[bel[r]],r,x);
    for(int i = bel[l] + 1;i < bel[r];++i) change2(i,x);
    return;
}
inline int ask1(int l,int r,int x) {
    int res = 0;
    for(int i = l;i <= r;++i) {
        if(a[getf(i)] - tag[bel[i]] == x) res++;
    }
    return res;
}
inline int ask2(int num,int val) {
    if(val + tag[num] >= 100000) return 0;
    return cnt[root[num][val + tag[num]]];
}
inline int query(int l,int r,int x) {
    if(bel[l] + 1 >= bel[r]) return ask1(l,r,x);
    int res = ask1(l,br[bel[l]],x) + ask1(bl[bel[r]],r,x);
    for(int i = bel[l] + 1;i < bel[r];i++) res += ask2(i,x);
    return res;
}
int main() {
    n = read();m = read();bls = sqrt(n) + 1;
    for(register int i = 1;i <= n;++i) {
        a[i] = read();
        bel[i] = (i - 1) / bls + 1;
        if(!bl[bel[i]]) bl[bel[i]] = i;
        br[bel[i]] = i;
    }
    for(register int i = 1;i <= bel[n];++i) build(i);
    while(m--) {
        int opt,l,r,x;opt = read();l = read();r = read();x = read();
        if(opt == 1) modify(l,r,x);
        else {
            print(query(l,r,x));
        }
    }
    fwrite(pbuf,1,pp-pbuf,stdout);
    return 0;
}

原文地址:https://www.cnblogs.com/Sai0511/p/10360348.html

时间: 2024-08-30 14:04:15

【[Ynoi2018]五彩斑斓的世界】的相关文章

题解 P4117 【[Ynoi2018]五彩斑斓的世界】

题目链接 我觉得AVX2指令集不够爽,于是写了AVX512.到官网查了一天手册,直接拿下最优解 Solution [Ynoi2018]五彩斑斓的世界 题目大意:给定一个长度为\(n\)的序列.每次将\([l,r]\)内大于\(x\)的数减\(x\).询问\([l,r]\)内\(x\)出现了多少次 分析:还能有啥分析,直接暴力,指令集优化一下就可以了 所有函数都可以在Intel手册查到 首先,既然我们要用指令集,得\(CPU\)资瓷才行 #include <stdint.h> #include

[Ynoi2018]未来日记

"望月悲叹的最初分块" (妈呀这名字好中二啊(谁叫我要用日本轻小说中的东西命名真是作死)) 这里就直接挂csy的题解了,和我的不太一样,但是大概思路还是差不多的,我的做法是和“五彩斑斓的世界”有点类似的维护方法 先考虑如何求区间第k小值.对序列和权值都进行分块,设bi,j表示前j 块中权值在i 块内的数字个数,ci,j 表示前j 块中数字i 的出现次数.那么对于一个询问[l,r] ,首先将零碎部分的贡献加入到临时数组tb 和tc 中,然后枚举答案位于哪一块,确定位于哪一块之后再暴力枚举

第1章:我是程序员

青春是什么?也许,青春就是一种回忆,一种奋斗,徘徊在人生道路,也许是迷茫,也许是憧憬,不变的是时间匆匆的流逝...我们慨叹生活,慨叹过去,不经意之间,人生的彷徨,让我们迷失过去,但是,人生,就是一种酸甜苦辣,我们不知道自己会遇到什么,唯有的是努力,努力,还有努力...青春,是你的故事,我的故事,五彩斑斓的世界,青春的梦想....驰骋在我们的内心中...有我们的感动... 第1章 不眠的夜晚----- 莫言,一个菜鸟级别的程序员,此时,已经深夜了...他却睡不着,辗转反侧,程序已经调试很多次了,但

书上的美来自生活

童年,是人生最美好的阶段. 一个人对生活审美感受的培养,最好的阶段,也是在童年.童年的世界,是五彩斑斓的,要投身于这五彩斑斓的世界中,并在心底里,深深地爱上它们.那么,五彩斑斓的光,投射到文字里,就会像梦幻一般,闪烁着童稚而纯朴的美. 也就是说,好的作文,要从生活中来. 这样,我们就必须要有一颗懂得观察生活的心.冰雪的融化,春草的发芽,小虫子的爬行,蚂蚁的决战,云的倏忽飞动,鸟的腾挪跌宕,等等,这一切都要留意观察.还有,雨后的蛙声,晚秋的蝉鸣,高枝上的莺啼,耕作的老牛的哞叫,你们都要留意,去听,

好的作文,要从生活中来

童年,是人生最美好的阶段. 一个人对生活审美感受的培养,最好的阶段,也是在童年.童年的世界,是五彩斑斓的,要投身于这五彩斑斓的世界中,并在心底里,深深地爱上它们.那么,五彩斑斓的光,投射到文字里,就会像梦幻一般,闪烁着童稚而纯朴的美. 也就是说,好的作文,要从生活中来. 这样,我们就必须要有一颗懂得观察生活的心.冰雪的融化,春草的发芽,小虫子的爬行,蚂蚁的决战,云的倏忽飞动,鸟的腾挪跌宕,等等,这一切都要留意观察.还有,雨后的蛙声,晚秋的蝉鸣,高枝上的莺啼,耕作的老牛的哞叫,你们都要留意,去听,

学习SpirngMVC之如何获取请求参数

学习SpringMVC——如何获取请求参数 @RequestParam,你一定见过:@PathVariable,你肯定也知道:@QueryParam,你怎么会不晓得?!还有你熟悉的他(@CookieValue)!她(@ModelAndView)!它(@ModelAttribute)!没错,仅注解这块,spring mvc就为你打开了五彩斑斓的世界.来来来,不要兴(mi)奋(hu),坐下来,我们好好聊聊这么些个注解兄弟们~~~(wait, 都没有听过? 好,来,你坐前排,就你!) 一.spring

java架构解密——Spring框架的AOP

一直以来,我们应用了不少的AOP框架,但是对于AOP的底层实现却没有过多的深入,古话就是"知其然,不知其所以然",随着AOP学术讨论的骤然兴起,我也开拓了自己的眼界,深入了解了AOP这个五彩斑斓的世界! 先来看看大众的定义: 百度百科: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函

百度发布“无人挖掘机”,吹的牛实现后李彦宏又立了3个flag

导读:AI时代到来了,这个世界会因为AI变得更好吗?YES, AI DO. 来源:百度 01 李彦宏立的3个flag 7月4日百度 AI 开发者大会上,李彦宏说:"曾经吹过的牛实现了,全球首款 L4 级量产自动驾驶巴士'阿波龙'量产下线!" 如今,阿波龙已经安全运营了整整120天. 4个月后的现在,李彦宏在百度世界大会上又立了三个 flag: Flag 1:百度即将发布与一汽红旗合作的 L4 级自动驾驶量产乘用车 百度与一汽红旗合作,共同打造了中国首款 L4 级自动驾驶量产乘用车,并发

妈妈,请原谅我的年少无知,让我再爱您一次

美国每年5月的第二个星期日是母亲节,潜移默化下我国现在过的母亲节也是每年5月的第二个星期日.上周,母亲节如期而至,在这样一个美好的日子里,你为你的母亲做了什么呢? 亲手为她制作了一份小礼物?送了她一束康乃馨?为她洗了一次头.洗了一次脚?给她买了一个她喜欢很久的小礼物?等等,或者,你什么都没做,但是你却默默地陪在她的身边和她聊天谈心. 小编记得小时候看过一则"妈妈洗脚"的广告,相信很多人都看过.视频中妈妈在给姥姥洗脚,孩子在耳濡目染的情况下为妈妈也端来了一盆洗脚水并仔细的为妈妈洗着脚.这