[洛谷P3987]我永远喜欢珂朵莉~

题目大意:

给你\(n(n\le10^5)\)个数\(A_{1\sim n}(A_i\le5\times10^5)\),\(m(m\le5\times10^5)\)次操作,操作包含以下两种:

  1. 将区间\([l,r]\)间所有\(v\)的倍数除以\(v\)。
  2. 求区间\([l,r]\)所有数之和。

思路1:

对范围内要用到的每个质因数开一个set维护包含该质因子的\(A_i\)下标。

对于操作\(1\),将\(v\)分解质因数,在set中查找下标在\([l,r]\)中的满足条件的数。并将这些数\(\div v\)。若操作过后不包含该质因数,则将其从set中删去。

对于操作\(2\),用树状数组维护即可。

源代码1:

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
#include<sys/mman.h>
#include<sys/stat.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
class MMapInput {private:char *buf,*p;int size;public:MMapInput() {register int fd=fileno(stdin);struct stat sb;fstat(fd,&sb);size=sb.st_size;buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0));p=buf;}char getchar() {return (p==buf+size||*p==EOF)?EOF:*p++;}
};
MMapInput mmi;
inline int getint() {register char ch;while(!isdigit(ch=mmi.getchar()));register int x=ch^'0';while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0');return x;
}
typedef __gnu_pbds::tree<int,__gnu_pbds::null_type,std::less<int>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update> rbtree;
typedef long long int64;
const int N=1e5+1,M=1e5,A=1e6+1,P=78499;
bool vis[A];
int a[N],n,m,p[P],fail[N];
inline void sieve() {for(register int i=2;i<A;i++) {if(vis[i]) continue;p[++p[0]]=i;for(register int j=i*2;j<A;j+=i) {vis[j]=true;}}
}
rbtree set[P];
class FenwickTree {private:int64 val[N];int lowbit(const int &x) const {return x&-x;}public:void modify(int p,const int &x) {for(;p<=n;p+=lowbit(p)) val[p]+=x;}int64 query(int p) const {int64 ret=0;for(;p;p-=lowbit(p)) ret+=val[p];return ret;}int64 query(const int &l,const int &r) const {return query(r)-query(l-1);}
};
FenwickTree t;
int main() {sieve();n=getint(),m=getint();for(register int i=1;i<=n;i++) {a[i]=getint();t.modify(i,a[i]);int tmp=a[i];for(register int j=1;p[j]*p[j]<=tmp;j++) {if(tmp%p[j]==0) {set[j].insert(i);while(tmp%p[j]==0) {tmp/=p[j];}}}if(tmp!=1) {set[std::lower_bound(&p[1],&p[p[0]]+1,tmp)-p].insert(i);}}for(register int tim=1;tim<=m;tim++) {const int opt=getint();const int l=getint(),r=getint();if(opt==1) {const int tmp=getint();int v=tmp;for(register int i=1;p[i]*p[i]<=v;i++) {if(v%p[i]!=0) continue;int sum=1;for(;v%p[i]==0;v/=p[i]) sum*=p[i];const rbtree::iterator begin=set[i].lower_bound(l);const rbtree::iterator end=set[i].upper_bound(r);if(v==1) {for(rbtree::iterator it=begin;it!=end;) {if(a[*it]%p[i]!=0) {set[i].erase(it++);continue;}if(a[*it]%tmp==0&&fail[*it]<tim) {t.modify(*it,a[*it]/tmp-a[*it]);a[*it]/=tmp;}it++;}continue;}for(rbtree::iterator it=begin;it!=end;) {if(a[*it]%p[i]!=0) {set[i].erase(it++);continue;}if(a[*it]%sum!=0) fail[*it]=tim;it++;}}if(v!=1) {const int i=std::lower_bound(&p[1],&p[p[0]]+1,v)-p;const rbtree::iterator begin=set[i].lower_bound(l);const rbtree::iterator end=set[i].upper_bound(r);for(rbtree::iterator it=begin;it!=end;) {if(a[*it]%v!=0) {set[i].erase(it++);continue;}if(a[*it]%tmp==0&&fail[*it]<tim) {t.modify(*it,a[*it]/tmp-a[*it]);a[*it]/=tmp;}it++;}}}if(opt==2) {printf("%lld\n",t.query(l,r));}}return 0;
}

思路2:

本题是某年CCF-CSP原题,用当时原题的数据,上面的做法是过不了的。

考虑不要按照质因数维护set,将操作离线,对于每个\(v\)维护一个set。然后卡卡常就过了。

源代码:

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
#include<sys/mman.h>
#include<sys/stat.h>
#include<ext/pb_ds/assoc_container.hpp>
class MMapInput {private:char *buf,*p;int size;public:MMapInput() {register int fd=fileno(stdin);struct stat sb;fstat(fd,&sb);size=sb.st_size;buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0));p=buf;}char getchar() {return (p==buf+size||*p==EOF)?EOF:*p++;}
};
MMapInput mmi;
inline int getint() {register char ch;while(!isdigit(ch=mmi.getchar()));register int x=ch^'0';while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0');return x;
}
typedef long long int64;
const int N=1e5+1,M=1e5,A=5e5+1;
int n,a[N];
struct Opt {int type,l,r,v;
};
Opt o[M];
std::set<int> set[M];
std::vector<int> vec;
int id[A];
class FenwickTree {private:int64 val[N];int lowbit(const int &x) const {return x&-x;}public:void modify(int p,const int &x) {for(;p<=n;p+=lowbit(p)) val[p]+=x;}int64 query(int p) const {int64 ret=0;for(;p;p-=lowbit(p)) ret+=val[p];return ret;}int64 query(const int &l,const int &r) const {return query(r)-query(l-1);}
};
FenwickTree t;
int main() {n=getint();const int m=getint();for(register int i=1;i<=n;i++) {t.modify(i,a[i]=getint());}for(register int i=0;i<m;i++) {o[i].type=getint();o[i].l=getint();o[i].r=getint();if(o[i].type==1) {o[i].v=getint();if(o[i].v==1) continue;vec.push_back(o[i].v);}}std::sort(vec.begin(),vec.end());vec.resize(std::unique(vec.begin(),vec.end())-vec.begin());std::fill(&id[0],&id[A],-1);for(register unsigned i=0;i<vec.size();i++) id[vec[i]]=i;for(register int i=1;i<=n;i++) {for(register int j=1;j*j<=a[i];j++) {if(a[i]%j!=0) continue;if(id[j]!=-1) set[id[j]].insert(i);if(id[a[i]/j]!=-1) set[id[a[i]/j]].insert(i);}}for(register int i=0;i<m;i++) {const int &opt=o[i].type,&l=o[i].l,&r=o[i].r;if(opt==1) {const int &v=o[i].v;if(v==1) continue;const std::set<int>::iterator begin=set[id[v]].lower_bound(l);const std::set<int>::iterator end=set[id[v]].upper_bound(r);for(register std::set<int>::iterator i=begin;i!=end;) {if(a[*i]%v!=0) {set[id[v]].erase(i++);continue;}t.modify(*i,a[*i]/v-a[*i]);a[*i]/=v;if(a[*i]%v!=0) {set[id[v]].erase(i++);continue;}++i;}}if(opt==2) {printf("%lld\n",t.query(l,r));}}return 0;
}

转载于:https://www.cnblogs.com/skylee03/p/9379168.html

[洛谷P3987]我永远喜欢珂朵莉~相关推荐

  1. 洛谷P3987 我永远喜欢珂朵莉~ 树状数组+vector(暴力)

    题目链接:我永远喜欢珂朵莉- 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到 ...

  2. 洛谷P3987 我永远喜欢珂朵莉~(set 树状数组)

    题意 题目链接 Sol 不会卡常,自愧不如.下面的代码只有66分.我实在懒得手写平衡树了.. 思路比较直观:拿个set维护每个数出现的位置,再写个线段树维护区间和 #include<bits/s ...

  3. 珂朵莉树(永远喜欢珂朵莉/doge)

    目录 前言 可能用到前置知识 背景 构建珂朵莉树 核心函数 珂朵莉树在实际题目使用 对珂朵莉树的一些感想 最后的最后 前言 最近刚刚学内容大概是借鉴的吧,感觉这个数据结构不仅简单,还很强,有着非常柯学 ...

  4. [转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解

    参考资料: Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索) 毒瘤数据结构之珂朵莉树 在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵 ...

  5. 一种黑科技:珂朵莉树

    首先要明白的是:珂朵莉树(ODT)是一种用来骗分的暴力数据结构. 珂朵莉树的思想是利用集合set,把相同且连续的元素合并为一个个区间,从而进行区间修改:因此,珂朵莉树是区间的集合,这点可以通过定义结构 ...

  6. 浅谈珂朵莉树(ODT)

    前言 珂学家狂喜( 文章目录 前言 一.珂朵莉树来源 二.珂朵莉树 1.珂朵莉树有什么用? 2.原理是什么? a.存储 b.分割结点 c.推平 d.剩余操作 3.复杂度分析 三.珂朵莉树例题 1.P4 ...

  7. 浅谈珂朵莉树(Chtholly Tree)——暴力而玄学的数据结构

    关于它很珂学的名字- 珂朵莉树(Chtholly Tree),又称老司机树(Old Driver Tree),起源于CodeFoeces平台上编号为896C的一道题-- " Willem, ...

  8. 我的算法不可能这么简单—珂朵莉树

    文章目录 进入正题 珂朵莉树的起源 题目简述 题目分析 珂朵莉树的实现 萌新三连 1.明明查询的右端点是12,但是要split(13)呢? 2.为什么要先分裂右端点,然后再分裂左端点呢? 3.获取到区 ...

  9. CF915E Physical Education Lessons(珂朵莉树)

    中文题面 据说正解是动态开点线段树而且标记也不难下传的样子 然而这种区间推平的题目还是喜欢写珂朵莉树啊--码量小-- 虽然真要构造的话随便卡-- 1 //minamoto 2 #include< ...

  10. 牛客练习赛7 E 珂朵莉的数列

    珂朵莉的数列 思路: 树状数组+高精度 离散化不知道哪里写错了,一直wa,最后用二分写的离散化 哪位路过大神可以帮我看看原来的那个离散化错在哪里啊 通过代码: import java.math.Big ...

最新文章

  1. React 中报错:Unexpected reserved word ‘await‘
  2. sas中的sql(2) 行选择 、限制重复、条件运算符、运行前语法检查、feedback、count...
  3. 拳王虚拟项目公社:怎么找低价电影票,低价电影票怎样赚钱,低价电影票实操赚钱方法?
  4. matlab合成音乐原理,matlab 做音乐合成
  5. L2-022 重排链表-PAT团体程序设计天梯赛GPLT
  6. 【基础】网络常见的9大命令,非常实用!
  7. 数据预处理与特征工程—6.Kaggle房价预测中数据预处理与特征工程
  8. 微信公众平台开发,图文回复、access_token生成调用、以及微信SDK的实现(2)
  9. adb连接 红米5手机
  10. 未来教育计算机题库三合一,未来教育-全国计算机等级考试真考题库、高频考点、模拟考场三合一(二级MS Office高级应用)...
  11. 安装mysql数据库出现问题_安装mysql数据库及问题解决方法
  12. 年薪200万是怎样的一种体验?
  13. 计算机教室布置软木,软木照片墙布置,让孩子体验手工的乐趣
  14. 16,甲流疫情死亡率
  15. java语言程序设计与数据结构基础篇,2万字20个项目实例
  16. re-id #issue
  17. raid中条带概念问题
  18. Hello MySQL(十三)——事务和锁
  19. 记一次vue^2.6.5-router^3.0.6的keep-alive事故
  20. C语言实现3个数大小比较

热门文章

  1. 串口协议和RS-232标准,以及RS232电平与TTL电平的区别,“USB/TTL转232“模块(以CH340芯片模块为例)的工作原理。
  2. 用c++写bilibili番剧抢楼程序
  3. python爬取豆瓣书评排行榜_爬虫:爬取豆瓣读书排行榜
  4. php获取文件名和后缀名
  5. Debian10安装Chromium浏览器
  6. csgo服务器怎么显示cmd,CSGO服务器搭建教程——KZ模式
  7. 组图:释放性感诱惑 内地超级豪放女星大盘点
  8. android指纹采集sdk,SDK上的Android指纹23
  9. pyhanlp常用功能简单总结
  10. 办公室计算机打印机共享,办公室小技巧:如何设置共享打印机