成段更新

A Simple Problem with Integers http://poj.org/problem?id=3468

 1 #include<cstdio>
 2 #define lrrt int L,int R,int rt
 3 #define iall 1,n,1
 4 #define imid int mid=(L+R)>>1
 5 #define lson L,mid,rt<<1
 6 #define rson mid+1,R,rt<<1|1
 7 typedef __int64 LL;
 8 const int M=100010;
 9 int a[M];
10 struct T{
11     LL sum,lazy;
12 }tree[M<<2];
13 void pushup(int rt){
14     tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
15 }
16 void build(lrrt){
17     tree[rt].lazy=0;
18     if(L==R){
19         tree[rt].sum=a[L];
20         return ;
21     }
22     imid;
23     build(lson);
24     build(rson);
25     pushup(rt);
26 }
27 void pushdown(int mid,lrrt){
28     if(tree[rt].lazy){
29         tree[rt<<1].lazy+=tree[rt].lazy;
30         tree[rt<<1|1].lazy+=tree[rt].lazy;
31         tree[rt<<1].sum+=(mid-L+1)*tree[rt].lazy;
32         tree[rt<<1|1].sum+=(R-mid)*tree[rt].lazy;
33         tree[rt].lazy=0;
34     }
35 }
36 void update(int x,int y,int z,lrrt){
37     if(x<=L&&R<=y){
38         tree[rt].sum+=(R-L+1)*z;
39         tree[rt].lazy+=z;
40         return ;
41     }
42     imid;
43     pushdown(mid,L,R,rt);
44     if(mid>=x) update(x,y,z,lson);
45     if(mid<y)  update(x,y,z,rson);
46     pushup(rt);
47 }
48 LL query(int x,int y,lrrt){
49     if(x<=L&&R<=y) return tree[rt].sum;
50     imid;
51     pushdown(mid,L,R,rt);
52     LL ans=0;
53     if(mid>=x) ans+=query(x,y,lson);
54     if(mid<y)  ans+=query(x,y,rson);
55     return ans;
56 }
57 int main(){
58     int n,m;
59     while(~scanf("%d%d",&n,&m)){
60         for(int i=1;i<=n;i++){
61             scanf("%d",&a[i]);
62         }
63         build(iall);
64         while(m--){
65             char op[4];
66             int x,y,z;
67             scanf("%s%d%d",op,&x,&y);
68             if(op[0]==‘C‘){
69                 scanf("%d",&z);
70                 update(x,y,z,iall);
71             }
72             else{
73                 printf("%I64d\n",query(x,y,iall));
74             }
75         }
76     }
77     return 0;
78 }

Mayor‘s posters http://poj.org/problem?id=2528

离散化

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<map>
 5 #define mt(a,b) memset(a,b,sizeof(a))
 6 #define lrrt int L,int R,int rt
 7 #define iall 1,n,1
 8 #define imid int mid=(L+R)>>1
 9 #define lson L,mid,rt<<1
10 #define rson mid+1,R,rt<<1|1
11 using namespace std;
12 const int M=10000010;
13 struct Input{
14     int x,y;
15 }in[10010];
16 int tos[20010];
17 int tohash[M];
18 int tree[M<<2];
19 void build(lrrt){
20     tree[rt]=0;
21     if(L==R) return ;
22     imid;
23     build(lson);
24     build(rson);
25 }
26 void pushdown(int rt){
27     if(tree[rt]){
28         tree[rt<<1]=tree[rt];
29         tree[rt<<1|1]=tree[rt];
30         tree[rt]=0;
31     }
32 }
33 void update(int x,int y,int z,lrrt){
34     if(x<=L&&R<=y){
35         tree[rt]=z;
36         return ;
37     }
38     pushdown(rt);
39     imid;
40     if(mid>=x) update(x,y,z,lson);
41     if(mid<y)  update(x,y,z,rson);
42 }
43 bool vis[M];
44 void query(lrrt){
45     if(L==R){
46         vis[tree[rt]]=true;
47         return ;
48     }
49     pushdown(rt);
50     imid;
51     query(lson);
52     query(rson);
53 }
54 int main(){
55     int t,m;
56     while(~scanf("%d",&t)){
57         while(t--){
58             scanf("%d",&m);
59             int lt=0;
60             for(int i=1;i<=m;i++){
61                 scanf("%d%d",&in[i].x,&in[i].y);
62                 tos[lt++]=in[i].x;
63                 tos[lt++]=in[i].y;
64             }
65             sort(tos,tos+lt);
66             lt=unique(tos,tos+lt)-tos;
67             int n=1;
68             for(int i=0;i<lt;i++){
69                 tohash[tos[i]]=n;
70                 n++;
71                 if(tos[i+1]>tos[i]+1) n++;
72             }
73             build(iall);
74             for(int i=1;i<=m;i++){
75                 update(tohash[in[i].x],tohash[in[i].y],i,iall);
76             }
77             mt(vis,0);
78             query(iall);
79             int ans=0;
80             for(int i=1;i<=m;i++){
81                 if(vis[i]) ans++;
82             }
83             printf("%d\n",ans);
84         }
85     }
86     return 0;
87 }

end

成段更新,布布扣,bubuko.com

时间: 2024-11-06 19:17:36

成段更新的相关文章

Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题是线段树成段更新,但是不能直接更新,不然只能一个数一个数更新.这样只能把每个数存到一个数组中,长度大概是20吧,然后模拟二进制的位操作.仔细一点就行了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath>

POJ 2777 Count Color (线段树成段更新+二进制思维)

题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种. 很明显的线段树成段更新,但是查询却不好弄.经过提醒,发现颜色的种类最多不超过30种,所以我们用二进制的思维解决这个问题,颜色1可以用二进制的1表示,同理,颜色2用二进制的10表示,3用100,....假设有一个区间有颜色2和颜色3,那么区间的值为二进制的110(十进制为6).那我们就把

POJ 2528 Mayor&#39;s posters (hash+线段树成段更新)

题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度.现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW.后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报.现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到.) 思路:简单的成段更新,但是数据量是1千万,会MT,所以要区间压缩(离散化),保证覆盖的关系不变,离散化的时候有个易错的细节,poj数据水了,这个易错点引用h

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace

Light OJ 1411 Rip Van Winkle`s Code 线段树成段更新

题目来源:Light OJ 1411 Rip Van Winkle`s Code 题意:3中操作 1种查询 求区间和 其中每次可以把一段区间从左到右加上1,2,3,...或者从右到左加上...3,2,1 或者把某个区间的数都置为v 思路:我是加了6个域 add是这段区间每个数都要加上add  add是这么来的 对与123456...这个等差数列 可能要分为2个区间 那么我就分成123和123 两个右边的等差数列每个数还应该加上3 所以右区间add加3 v是这个区间都要置为v 他的优先级最高 b是

HDU1698 Just a Hook 【线段树】+【成段更新】+【lazy标记】

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15889    Accepted Submission(s): 7897 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible thing

poj 3468 A Simple Problem with Integers (线段树成段更新)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 77486   Accepted: 23862 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

poj 3468 A Simple Problem with Integers 【线段树-成段更新】

题目:poj 3468 A Simple Problem with Integers 题意:给出n个数,两种操作 1:l -- r 上的所有值加一个值val 2:求l---r 区间上的和 分析:线段树成段更新,成段求和 树中的每个点设两个变量sum 和 num ,分别保存区间 l--r 的和 和l---r 每个值要加的值 对于更新操作:对于要更新到的区间上面的区间,直接进行操作 加上 (r - l +1)* val .下面的区间标记num += val 对于求和操作,每次进行延迟更新,把num值

poj3468A Simple Problem with Integers(线段树+成段更新)

题目链接: huangjing题意: 给n个数,然后有两种操作. [1]Q a b 询问a到b区间的和. [2]C a b c将区间a到b的值都增加c. 思路: 线段树成段更新的入门题目..学会使用lazy即可.还需要注意的是,lazy的时候更改是累加,而不是直接修改..有可能连续几次进行修改操作..注意这一点就好了... 题目: Language: Default A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: