除法

201709-5

  • 这道题有很多种方法来做,最常用的就是线段树和树状数组。
  • 如果使用线段树来做,就会想到区间修改的update函数。但是这里可能会涉及到v是1或者a[j]是0的情况,所以用这种方法会超时,最多50分。
  • 可以修改一下代码,使用点修改来做这道题。在main函数里面增加一个循环,用来判断。
  • 当然,还有一种方法就是树状数组,这种方法和上面这种方法运行时间相差无几,但是代码量大大减少。
  • 需要注意的是,如果v是long long型,最好不要用scanf %lld的方式读入,否则超时。

使用线段树代码:

//线段树求解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100005;
int n,m;
int a[maxn];
long long sum[maxn<<2];
void pushup(int id,int l,int r){
int lc=id<<1;
int rc=id<<1|1;
sum[id]=sum[lc]+sum[rc];
}
void build(int id,int l,int r){
if(l==r){
sum[id]=a[l];
return;
}
int mid=(l+r)>>1;
int lc=id<<1;
int rc=id<<1|1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(id,l,r);
}
//---------------------------区间修改
// void update(int id,int l,int r,int p,int q,int v){
// if(l==r){
// if(sum[id]>=v&&sum[id]%v==0)
// sum[id]/=v;
// return;
// }
// int mid=(l+r)>>1;
// if(p<=mid){
// update(id<<1,l,mid,p,q,v);
// }
// if(q>mid){
// update(id<<1|1,mid+1,r,p,q,v);
// }
// pushup(id,l,r);
// }
//-------------------------------点修改
void update(int id,int l,int r,int p){
if(l==r){
sum[id]=a[p];
return;
}
int mid=(l+r)>>1;
if(p<=mid){
update(id<<1,l,mid,p);
}
if(p>mid){
update(id<<1|1,mid+1,r,p);
}
pushup(id,l,r);
}
long long query(int id,int l,int r,int p,int q){
long long sums=0;
if(p<=l&&q>=r){
return sum[id];
}
int mid=(l+r)>>1;
if(p<=mid){
sums+=query(id<<1,l,mid,p,q);
}
if(q>mid){
sums+=query(id<<1|1,mid+1,r,p,q);
}
return sums;
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0);
scanf("%d%d",&n,&m);
//cin>>n>>m;
for(int i=1;i<=n;i++){
//cin>>a[i];
scanf("%d",&a[i]);
}
build(1,1,n);
for(int i=0;i<m;i++){
int opt,p,q;
scanf("%d%d%d",&opt,&p,&q);
//cin>>opt>>p>>q;
if(opt==1){//update
int v;
scanf("%d",&v);
//cout<<v<<endl;
//cin>>v;
//-------------------------------区间修改
// if(v==1)
// continue;
// update(1,1,n,p,q,v);
if(v==1)
continue;
// //--------------------------点修改
for(int j=p;j<=q;j++){
if(a[j]>=v&&a[j]%v==0){
a[j]/=v;
update(1,1,n,j);
}
}
}else{
cout<<query(1,1,n,p,q)<<endl;
}
}
//system("pause");
return 0;
}

使用树状数组代码:

//树状数组求解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100005;
int n,m;
int a[maxn];
long long c[maxn];
int lowbit(int x){
return x&(-x);
}
long long sum(int x){
long long ret=0;
while(x>0){
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void add(int x,int v){
while(x<=n){
c[x]+=v;
x+=lowbit(x);
}
}
int main(){
// ios::sync_with_stdio(false);
// cin.tie(0);
//cin>>n>>m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
//cin>>a[i];
scanf("%d",&a[i]);
add(i,a[i]);
}
for(int i=0;i<m;i++){
int opt;
//cin>>opt;
scanf("%d",&opt);
if(opt==1){
int p,q;int v;
//cin>>p>>q>>v;
scanf("%d%d%d",&p,&q,&v);//这里不能用%lld来读取long long 型,
if(v==1)
continue;
for(int j=p;j<=q;j++){
if(a[j]>=v&&a[j]%v==0){
add(j,a[j]/v-a[j]);
a[j]/=v;
}
}
}else{
int p,q;
//cin>>p>>q;
scanf("%d%d",&p,&q);
cout<<sum(q)-sum(p-1)<<endl;
}
}
//system("pause");
return 0;
}

CCF(除法):线段树区间修改(50分)+线段树点修改(100分)+线段树(100分)的更多相关文章

  1. 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并

    题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...

  2. POJ 2528 ——Mayor's posters(线段树+区间操作)

    Time limit 1000 ms Memory limit 65536 kB Description The citizens of Bytetown, AB, could not stand t ...

  3. hdu 3308(线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. codevs 1690 开关灯 线段树区间更新 区间查询Lazy

    题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人 ...

  5. hiho_1078_线段树区间修改

    题目 给定一组数,要求进行若干次操作,这些操作可以分为两种类型: (1) CMD 1 beg end value 将数组中下标在[beg, end] 区间内数字都变为value (2) CMD 2 b ...

  6. hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)

    #1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...

  7. Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)

    题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...

  8. HDU - 3974 Assign the task (线段树区间修改+构建模型)

    https://cn.vjudge.net/problem/HDU-3974 题意 有一棵树,给一个结点分配任务时,其子树的所有结点都能接受到此任务.有两个操作,C x表示查询x结点此时任务编号,T ...

  9. 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)

    Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...

随机推荐

  1. 树链剖分(附带LCA和换根)——基于dfs序的树上优化

    .... 有点懒: 需要先理解几个概念: 1. LCA 2. 线段树(熟练,要不代码能调一天) 3. 图论的基本知识(dfs序的性质) 这大概就好了: 定义: 1.重儿子:一个点所连点树size最大的 ...

  2. poj3415 Common Substrings (后缀数组+单调队列)

    Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9414   Accepted: 3123 Description A sub ...

  3. c语言实现链表增、删、改、查及文件读写 && 链表实现程序

    一.链表实现增删改查 1.链表定义 1 #include<stdio.h> 2 #include<string.h> 3 #include<windows.h> 4 ...

  4. Redis 事务 & 消息队列

    Redis 消息队列介绍 什么是消息队列 消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,有消息系统来确保信息的可靠传递,消息生产者只管把消息发布到消息队列中而不 ...

  5. 牛客国庆2 F-平衡二叉树【非原创】

    题目:戳这里 学习博客:戳这里

  6. hdu5693D++游戏 区间DP-暴力递归

    主要的收获是..如何优化你递推式里面不必要的决策 之前的代码 这个代码在HDU超时了,这就对了..这个复杂度爆炸.. 但是这个思路非常地耿直..那就是只需要暴力枚举删两个和删三个的情况,于是就非常耿直 ...

  7. js map & Number

    js map & Number const regionIds = `1,2,3`; // "1,2,3" regionIds.split(',').map(Number) ...

  8. iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug

    iPhone 12 Pro 屏幕时间设置的密码锁出现弹窗 UI 错位重大 Bug iOS 14.1 Bug 弹窗 UI 非常丑 弹窗屏占太高了 屏幕使用时间 https://support.apple ...

  9. 高阶类 & HOC & anonymous class extends

    高阶类 & HOC & anonymous class extends js 匿名 class extends / mix-ins / 多继承 高阶函数 HOF, 接收一个 funct ...

  10. 如何用 js 实现一个 new 函数

    如何用 js 实现一个 new 函数 原理 new 关键字实现经过了如下过程 创建一个空对象 obj = {} 链接到原型 obj.proto = constructor.prototype 绑定 t ...