CodeForces 438D The Child and Sequence(线段树)

题目:http://codeforces.com/problemset/problem/438/D

一个数取模n%m,有两种情况、

1.m>n, n%m=n;

2.m<=n, n%m<=n/2;

所以当m>n时,取模操作可以忽略。

每个a[i]最多需要log(a[i])次取模操作变为0,因此我们可以对所有取模进行暴力更新。最多要更新n*log(a[i])次,由于单次更新复杂度为log(n),所以总复杂度为n*logn*log(a[i]).

#include <bits/stdc++.h>

using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=111111;
int col[maxn<<2];
long long sum[maxn<<2],Max[maxn<<2];
int n,m;
void pushup(int rt){
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void build(int l,int r,int rt){
    if(l==r){
        cin>>sum[rt];
        Max[rt]=sum[rt];
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
int op,l,r,x;
void setvalue(int pos,int val,int l,int r,int rt){
    if(l==r){
        sum[rt]=Max[rt]=val;
        return;
    }
    int m=(l+r)>>1;
    if(pos<=m)setvalue(pos,val,lson);
    else setvalue(pos,val,rson);
    pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt){
    if(l==r){
        sum[rt]%=val;
        Max[rt]=sum[rt];
        return;
    }
    int m=(l+r)>>1;
    if(L<=m&&Max[rt<<1]>=val)update(L,R,val,lson);
    if(R>m&&Max[rt<<1|1]>=val)update(L,R,val,rson);
    pushup(rt);
}
long long query(int L,int R,int l,int r,int rt){
    if(L<=l&&R>=r)return sum[rt];
    long long ans=0;
    int m=(l+r)>>1;
    if(L<=m)ans+=query(L,R,lson);
    if(R>m)ans+=query(L,R,rson);
    return ans;
}
int main()
{
//    freopen("in","r",stdin);
    while(cin>>n>>m){
        build(1,n,1);
        while(m--){
            scanf("%d",&op);
            if(op==3){
                scanf("%d%d",&l,&x);
                setvalue(l,x,1,n,1);
            }
            else if(op==2){
                scanf("%d%d%d",&l,&r,&x);
                update(l,r,x,1,n,1);
            }
            else {
                scanf("%d%d",&l,&r);
                printf("%I64d\n",query(l,r,1,n,1));
            }
        }
    }
    return 0;
}

  

时间: 2024-09-30 00:43:48

CodeForces 438D The Child and Sequence(线段树)的相关文章

CF(438D) The Child and Sequence(线段树)

题意:对数列有三种操作: Print operation l,?r. Picks should write down the value of . Modulo operation l,?r,?x. Picks should perform assignment a[i]?=?a[i] mod x for each i (l?≤?i?≤?r). Set operation k,?x. Picks should set the value of a[k] to x (in other words

Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模

D. The Child and Sequence At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks. Fortunately, Picks remembers how to

cf250D. The Child and Sequence(线段树 均摊复杂度)

题意 题目链接 单点修改,区间mod,区间和 Sol 如果x > mod ,那么 x % mod < x / 2 证明: 即得易见平凡, 仿照上例显然, 留作习题答案略, 读者自证不难. 反之亦然同理, 推论自然成立, 略去过程Q.E.D., 由上可知证毕. 然后维护个最大值就做完了.. 复杂度不知道是一个log还是两个log,大概是两个吧(线段树一个+最多改log次.) #include<bits/stdc++.h> #define Pair pair<int, int&g

Codeforces Round #250 (Div. 1) D. The Child and Sequence (线段树)

题目链接:http://codeforces.com/problemset/problem/438/D 给你n个数,m个操作,1操作是查询l到r之间的和,2操作是将l到r之间大于等于x的数xor于x,3操作是将下标为k的数变为x. 注意成段更新的时候,遇到一个区间的最大值还小于x的话就停止更新. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5

CF438D The Child and Sequence 线段树

给定数列,区间查询和,区间取模,单点修改. n,m小于10^5 ...当区间最值小于模数时,就直接返回就好啦~ #include<cstdio> #include<iostream> #define R register int #define ls (tr<<1) #define rs (tr<<1|1) using namespace std; inline long long g() { register long long ret=0,fix=1;

hdu 4893 Wow! Such Sequence!(线段树)

题目链接:hdu 4983 Wow! Such Sequence! 题目大意:就是三种操作 1 k d, 修改k的为值增加d 2 l r, 查询l到r的区间和 3 l r, 间l到r区间上的所以数变成最近的斐波那契数,相等的话取向下取. 解题思路:线段树,对于每个节点新增一个bool表示该节点以下的位置是否都是斐波那契数. #include <cstdio> #include <cstring> #include <cstdlib> #include <algor

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&amp;二分&amp;思维)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 352    Accepted Submission(s): 104 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

codeforces 444 C. DZY Loves Colors(线段树)

题目大意: 1 l r x操作 讲 [l,r]上的节点涂成x颜色,并且每个节点的值都加上 |y-x| y为涂之前的颜色 2 l r  操作,求出[l,r]上的和. 思路分析: 如果一个区间为相同的颜色.那么我们才可以合并操作. 所以我们之前找相同的区间就好. 但是问题是如何合并操作. 那么我们定义一个val  表示这个区间每个位置上应该加上的值. pushdown 的时候这个值是可以相加的. #include <cstdio> #include <iostream> #includ

HDOJ 4893 Wow! Such Sequence! 线段树

http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:10万的区间,初始都为0,10万次操作,三种操作为单点修改,区间将每个数改成最近的斐波那契数,以及区间求和. 分析:用一个flag记录该段是否被改成斐波那契数,同时多维护一个sum1表示如果该段改成斐波那契数,区间和为多少.开始sum1为区间长度,之后在单点做了修改以后对其更新,需要的时候用其覆盖sum. 1 #include<cstdio> 2 #include<cstring>