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 typedef __int64 LL;
  6 const int MAXN = 1e5 + 5;
  7 struct segtree {
  8     int l , r;
  9     LL sum , Min;
 10 }T[MAXN << 2];
 11 LL res;
 12
 13 void init(int p , int l , int r) {
 14     int mid = (l + r) >> 1;
 15     T[p].l = l , T[p].r = r;
 16     if(l == r) {
 17         scanf("%I64d" , &T[p].sum);
 18         T[p].Min = T[p].sum;
 19         return ;
 20     }
 21     init(p << 1 , l , mid);
 22     init((p << 1)|1 , mid + 1 , r);
 23     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
 24     T[p].Min = (T[p << 1].Min > T[(p << 1)|1].Min ? T[p << 1].Min : T[(p << 1)|1].Min);
 25 }
 26
 27 void updata(int p , int l , int r , LL x) {
 28     int mid = (T[p].l + T[p].r) >> 1;
 29     if(T[p].Min < x) {
 30         return ;
 31     }
 32     if(T[p].l == T[p].r) {
 33         T[p].Min %= x;
 34         T[p].sum %= x;
 35         return ;
 36     }
 37     if(r <= mid) {
 38         updata(p << 1 , l , r , x);
 39     }
 40     else if(l > mid) {
 41         updata((p << 1)|1 , l , r , x);
 42     }
 43     else {
 44         updata(p << 1 , l , mid , x);
 45         updata((p << 1)|1 , mid + 1 , r , x);
 46     }
 47     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
 48     T[p].Min = (T[p << 1].Min > T[(p << 1)|1].Min ? T[p << 1].Min : T[(p << 1)|1].Min);
 49 }
 50
 51 void updata2(int p , int index , LL x) {
 52     int mid = (T[p].l + T[p].r) >> 1;
 53     if(T[p].l == T[p].r && T[p].l == index) {
 54         T[p].sum = T[p].Min = x;
 55         return ;
 56     }
 57     if(index <= mid) {
 58         updata2(p << 1 , index , x);
 59     }
 60     else {
 61         updata2((p << 1)|1 , index , x);
 62     }
 63     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
 64     T[p].Min = (T[p << 1].Min > T[(p << 1)|1].Min ? T[p << 1].Min : T[(p << 1)|1].Min);
 65 }
 66
 67 void query(int p , int l , int r) {
 68     int mid = (T[p].l + T[p].r) >> 1;
 69     if(l == T[p].l && T[p].r == r) {
 70         res += (LL)T[p].sum;
 71         return ;
 72     }
 73     if(r <= mid) {
 74         query(p << 1 , l , r);
 75     }
 76     else if(l > mid) {
 77         query((p << 1)|1 , l , r);
 78     }
 79     else {
 80         query(p << 1 , l , mid);
 81         query((p << 1)|1 , mid + 1 , r);
 82     }
 83 }
 84
 85 int main()
 86 {
 87     int n , m , l , r , c;
 88     LL x;
 89     scanf("%d %d" , &n , &m);
 90     init(1 , 1 , n);
 91     while(m--) {
 92         scanf("%d" , &c);
 93         if(c == 1) {
 94             scanf("%d %d" , &l , &r);
 95             res = 0;
 96             query(1 , l , r);
 97             printf("%I64d\n" , res);
 98         }
 99         else if(c == 2) {
100             scanf("%d %d %I64d" , &l , &r , &x);
101             updata(1 , l , r , x);
102             //cout << query(1 , 4 , 4) << endl;
103         }
104         else {
105             scanf("%d %I64d" , &l , &x);
106             updata2(1 , l , x);
107         }
108     }
109 }
时间: 2024-11-14 06:26:46

Codeforces Round #250 (Div. 1) D. The Child and Sequence (线段树)的相关文章

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

codeforces --- Round #250 (Div. 2) A. The Child and Homework

<传送门> 这题就是一个坑,尼玛wa了一大片啊. 自己被hack了,比赛结束后改了又wa两次才过. [题目大意] 其实就是一个猜题小技巧(联系自己初中考试的时候怎么猜题的,这题就好理解多了).这位同学是这样来选答案的:1.如果有一些选项长度至少比其他所有的描述短两倍,或至少超过所有其他的描述的两倍,那么孩子认为这个选择很可能是正确的.2.如果正好满足以上其中一种条件(重点),这个同学就会选择它,否则就选C.给你一个选择题,让你选择出这个同学将会选择的答案. [题目分析] 首先,这个题目就是一个

codeforces --- Round #250 (Div. 2) B. The Child and Set

<传送门> [题目大意] 给你一个sum和一个limit,现在要你在1~limit中找到一些数来使得这些数的和等于sum,如果能找到的话就输出找到的数的个数和这些数,未找到输出"-1". 比赛的时候被hack了. [题目分析] 这题需要将所有的数的lowbit先求出来,然后按照大小排序,然后从后往前判断,如果这个数小于sum那么这个数就是可以构成sum的数,选进去,完了以后判断sum的值是否为0就可以了.做题的时候没将题目理解透彻. #include<bits/std

Codeforces Round #250 (Div. 2)B. The Child and Set 暴力

B. The Child and Set 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 set of Picks. Fortunately, Picks remembers something about h

Codeforces Round #250 (Div. 1) B. The Child and Zoo(排序+并查集)(常规好题)

B. The Child and Zoo time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Of course our child likes walking in a zoo. The zoo has n areas, that are numbered from 1 to n. The i-th area contains 

Codeforces Round #250 (Div. 2) C. The Child and Toy 详解

output standard output On Children's Day, the child got a toy from Delayyy as a present. However, the child is so naughty that he can't wait to destroy the toy. The toy consists of n parts and m ropes. Each rope links two parts, but every pair of par

Codeforces Round #530 (Div. 2)F Cookies (树形dp+线段树)

题:https://codeforces.com/contest/1099/problem/F 题意:给定一个树,每个节点有俩个信息x和t,分别表示这个节点上的饼干个数和先手吃掉这个节点上一个饼干的的时间.然后有先手和后手俩个人. ?先手可以这么操作:在规定总时间T到达某个节点然后一定要返回根节点1,期间可以选择吃掉某些节点上的某些饼干(前提是保证剩下的时间能够回到根节点): ?后手可以这么操作:在先手到达的位置和这个位置的孩子之间的连边选择一条让先手吃得更多的边摧毁掉,也可以跳过这个过程: 问

Codeforces Round #250 (Div. 2) C、The Child and Toy

注意此题,每一个部分都有一个能量值v[i],他移除第i部分所需的能量是v[f[1]]+v[f[2]]+...+v[f[k]],其中f[1],f[2],...,f[k]是与i直接相连(且还未被移除)的部分的编号. 注意题目移除的都是与第i部分直接相连的部分的能量值, 将本题目简化得,只考虑两个点1和2,1和2相连,1的能量值是10,2的能量值是20, 移除绳子时,要保持能量最小,可以移除部分2,这样移除的能量就是与2相连的部分1的能量即是10: 故每次相连两部分都移除能量值大的即可 #includ

Codeforces Round #250 (Div. 2)——The Child and Set

题目链接 题意: 给定goal和limit,求1-limit中的若干个数,每一个数最多出现一次,且这些数的lowbit()值之和等于goal,假设存在这种一些数,输出个数和每一个数:否则-1 分析: 先考虑一下比較普通的情况,给一些数,和一个goal,问时候能达到.(最好还是设这些数已经从大到小排序) 考虑能否够贪心,对于当前的数x: 1.之后的数的和能等于x,那么假设x<=goal,显然必须选x: 2.之后的数的和能等于x-1,那么同上(这个情况就是二进制的情况) 3.之后的数的和不包含上述两