CCF(除法):线段树区间修改(50分)+线段树点修改(100分)+线段树(100分)
除法
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分)的更多相关文章
- 【bzoj3638】Cf172 k-Maximum Subsequence Sum  模拟费用流+线段树区间合并
		
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
 - POJ 2528 ——Mayor's posters(线段树+区间操作)
		
Time limit 1000 ms Memory limit 65536 kB Description The citizens of Bytetown, AB, could not stand t ...
 - hdu 3308(线段树区间合并)
		
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
 - codevs 1690 开关灯 线段树区间更新 区间查询Lazy
		
题目描述 Description YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人 ...
 - hiho_1078_线段树区间修改
		
题目 给定一组数,要求进行若干次操作,这些操作可以分为两种类型: (1) CMD 1 beg end value 将数组中下标在[beg, end] 区间内数字都变为value (2) CMD 2 b ...
 - hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)
		
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
 - 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序加上一个线 ...
 - HDU - 3974 Assign the task (线段树区间修改+构建模型)
		
https://cn.vjudge.net/problem/HDU-3974 题意 有一棵树,给一个结点分配任务时,其子树的所有结点都能接受到此任务.有两个操作,C x表示查询x结点此时任务编号,T ...
 - 题解报告: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 ...
 
随机推荐
- 【poj 2478】Farey Sequence(数论--欧拉函数 找规律求前缀和)
			
题意:定义 Fn 序列表示一串 <1 的分数,分数为最简分数,且分母 ≤n .问该序列的个数.(2≤N≤10^6) 解法:先暴力找规律(代码见屏蔽处),发现 Fn 序列的个数就是 Φ(1)~Φ( ...
 - Broken robot CodeForces - 24D (三对角矩阵简化高斯消元+概率dp)
			
题意: 有一个N行M列的矩阵,机器人最初位于第i行和第j列.然后,机器人可以在每一步都转到另一个单元.目的是转到最底部(第N个)行.机器人可以停留在当前单元格处,向左移动,向右移动或移动到当前位置下方 ...
 - HDU 2897 邂逅明下(巴士变形)
			
题意: 给你n个石子,你最少取p个,最多取q个,问谁能赢 题解: 变形版的巴什博弈,当n>=q+1的时候,那么还是以q+1为一组拿走,剩下一个(n%(q+1)),这个时候如果它小于p的话都直接输 ...
 - 哈希算法解决:HDU1686  &&  POJ2774  &&  POJ3261
			
HDU1686 题意: 找A串在B串中的出现次数(可重叠),可用KMP做,这里只提供哈希算法做的方法 题解: 先得到A串的hash值,然后在B中枚举起点,长度为lena的子串,检验hash值是否相同就 ...
 - Codeforces Round #680 (Div. 2, based on Moscow Team Olympiad)  C. Division   (数学)
			
题意:有两个数\(p\)和\(q\),找到一个最大的数\(x\),使得\(p\ mod\ x=0\)并且\(x\ mod\ q\ne 0\). 题解:首先,如果\(p\ mod\ q\ne0\),那么 ...
 - python代理池的构建3——爬取代理ip
			
上篇博客地址:python代理池的构建2--代理ip是否可用的处理和检查 一.基础爬虫模块(Base_spider.py) #-*-coding:utf-8-*- ''' 目标: 实现可以指定不同UR ...
 - Java15 运行Hello,world竟然不用javac?
			
喜欢尝鲜的我,装好了Java15,如下编写了一个输出语句:hello,world. 当我打开cmd准备运行的时候,惊呆了! 以前java8的时候不都是这样操作的吗?最初以为环境配置问题,可以即便在系统 ...
 - 爬虫入门一 基础知识 以及request
			
title: 爬虫入门一 基础知识 以及request date: 2020-03-05 14:43:00 categories: python tags: crawler 爬虫整体概述,基础知识. ...
 - oslab oranges  一个操作系统的实现 实验三 认识保护模式(二):分页
			
实验目的: 掌握内存分页机制 对应章节:3.3 实验内容: 1.认真阅读章节资料,掌握什么是分页机制 2. 调试代码,掌握分页机制基本方法与思路 – 代码3.22中,212行---237行,设置断点调 ...
 - codeforces 6D
			
D. Lizards and Basements 2 time limit per test 2 seconds memory limit per test 64 megabytes input st ...