[洛谷P3987]我永远喜欢珂朵莉~
[洛谷P3987]我永远喜欢珂朵莉~
题目大意:
给你\(n(n\le10^5)\)个数\(A_{1\sim n}(A_i\le5\times10^5)\),\(m(m\le5\times10^5)\)次操作,操作包含以下两种:
- 将区间\([l,r]\)间所有\(v\)的倍数除以\(v\)。
- 求区间\([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;
}
[洛谷P3987]我永远喜欢珂朵莉~的更多相关文章
- 洛谷P3987 我永远喜欢珂朵莉~(set 树状数组)
题意 题目链接 Sol 不会卡常,自愧不如.下面的代码只有66分.我实在懒得手写平衡树了.. 思路比较直观:拿个set维护每个数出现的位置,再写个线段树维护区间和 #include<bits/s ...
- [转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解
参考资料: Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索) 毒瘤数据结构之珂朵莉树 在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵 ...
- 洛谷AT2342 Train Service Planning(思维,动态规划,珂朵莉树)
洛谷题目传送门 神仙思维题还是要写点东西才好. 建立数学模型 这种很抽象的东西没有式子描述一下显然是下不了手的. 因为任何位置都以\(k\)为周期,所以我们只用关心一个周期,也就是以下数都在膜\(k\ ...
- 洛谷P4344 [SHOI2015]脑洞治疗仪(珂朵莉树)
传送门 看到区间推倒……推平就想到珂朵莉树 挖脑洞直接assign,填坑先数一遍再assign再暴力填,数数的话暴力数 //minamoto #include<iostream> #inc ...
- 洛谷P2787 语文1(chin1)- 理理思维(珂朵莉树)
传送门 一看到区间推倒……推平操作就想到珂朵莉树 区间推平直接assign,查询暴力,排序的话开一个桶统计,然后一个字母一个字母加就好了 开桶统计的时候忘了保存原来的左指针然后挂了233 //mina ...
- 洛谷P2082 区间覆盖(加强版)(珂朵莉树)
传送门 虽然是黄题而且还是一波离散就能解决的东西 然而珂朵莉树还是很好用 相当于一开始区间全为0,然后每一次区间赋值,问最后总权值 珂朵莉树搞一搞就好了 //minamoto #include< ...
- 洛谷P2572 [SCOI2010]序列操作(珂朵莉树)
传送门 珂朵莉树是个吼东西啊 这题线段树代码4k起步……珂朵莉树只要2k…… 虽然因为这题数据不随机所以珂朵莉树的复杂度实际上是错的…… 然而能过就行对不对…… (不过要是到时候noip我还真不敢打… ...
- 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树
正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...
- 洛谷 P5350 序列 珂朵莉树
题目描述 分析 操作一.二.三为珂朵莉树的基本操作,操作四.五.六稍作转化即可 不会珂朵莉树请移步至这里 求和操作 把每一段区间分别取出,暴力相加 ll qh(ll l,ll r){ it2=Spli ...
随机推荐
- 一款基于react-native的弹窗提示组件
介绍一款基于react-native的弹窗提示插件 react-native-ms , github地址:https://github.com/jiangzhenfei/react-native-ms ...
- 分布式系统的负载均衡以及ngnix负载均衡的五种策略
一般而言,有以下几种常见的负载均衡策略: 一.轮询. 特点:给每个请求标记一个序号,然后将请求依次派发到服务器节点中,适用于集群中各个节点提供服务能力等同且无状态的场景. 缺点:该策略将节点视为等同, ...
- URAL 2078~2089
URAL 2078~2089 A - Bowling game 题目描述:给出保龄球每一局击倒的球数,按照保龄球的规则,算出总得分的最小值和最大值. solution 首先是最小值:每一局第一球击倒\ ...
- angular项目中使用jQWidgets
Angular CLI with jQWidgets In this tutorial, we will show you how to use https://cli.angular.io/ alo ...
- 20165301陈潭飞2017-2018-2 20165301 实验三《Java面向对象程序设计》实验报告
2017-2018-2 20165301 实验三<Java面向对象程序设计>实验报告 一.敏捷开发与XP实践-1 实验要求: 在IDEA中使用工具(Code->Reformate C ...
- CSU 1355 地雷清除计划
题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1355 好题,根本想不到是网络流. 模型如图: 假想从右上角到左下角有一条阻拦线,我们就是 ...
- Hadoop(五)分布式集群中HDFS系统的各种角色
NameNode 学习目标 理解 namenode 的工作机制尤其是元数据管理机制,以增强对 HDFS 工作原理的 理解,及培养 hadoop 集群运营中“性能调优”.“namenode”故障问题的分 ...
- elementUI 学习入门之 checkbox 复选框
CheckBox 复选框 与单选框基本类似.如:按钮样式.带边框.复选框按钮大小. eg: <template> <el-checkbox-group v-model="s ...
- windows下运行命令行mysql,提示mysql不是内部命令,解决办法
1. 打开CMD命令行,连接本地mysql数据库:mysql -u root -p 提示‘mysql’不是本地命令,解决办法如下: 找到你安装的mysql的目录,打开当前目录下的bin文件夹,你可以看 ...
- 借助jxl将Excel中的数据注入到Bean中
前言 使用了Hibernate的项目中需要导入多张表的数据,但是我又不想写多次取出Excle数据放到Bean里的代码,于是写了个ExcleUtils来帮助我做这件事. 基本思路 技术上,首先肯定是要借 ...