xdoj-1279(有趣的线段树--吉司机?!)

题目链接

  一 核心:

  f(x)=91 (x<=100)

  f(x)=x-10 (x>100)

  那么同一区间就可能不同的操作,那么该怎么解决呢?

  我门直到同一区间的数据属于同一类别的时候再进行懒惰标记

  区间记录最大值_max  最小值_min(同时应该有两个懒惰标记)

  1) 最大值大于100 全部减去10

  2)最小值小于等于100 全部变成91

  注意懒惰标记的顺序,(2)应该在后面,想一想啊!

二 代码

 1 /*
 2   f(x)=91 (x<=100)
 3   f(x)=x-10 (x>101)
 4 */
 5 #include <bits/stdc++.h>
 6 using namespace std;
 7 #define lson l,m,rt*2
 8 #define rson m+1,r,rt*2+1
 9 const int N=1e5+7;
10 int sum[N*4],s[4*N],b[4*N];
11 int t1[N*4],t2[N*4];
12 int n,q;
13 void pushup (int rt) {
14     sum[rt]=sum[rt*2]+sum[rt*2+1];
15     s[rt]=min (s[rt*2],s[rt*2+1]);
16     b[rt]=max (b[rt*2],b[rt*2+1]);
17 }
18 void cover (int r1,int r2,int k) {
19     t1[r2]+=t1[r1];
20     sum[r2]-=k*10*t1[r1];
21     s[r2]-=10*t1[r1]; b[r2]-=10*t1[r1];
22 }
23 void c2 (int r1,int r2,int k) {
24     t2[r2]=1;
25     sum[r2]=91*k;
26     s[r2]=b[r2]=91;
27 }
28 void pushdown (int rt,int l,int r) {
29     int m=(l+r)/2;
30     if (t1[rt]) {
31         cover (rt,rt*2,m-l+1);
32         cover (rt,rt*2+1,r-m);
33         t1[rt]=0;
34     }
35     if (t2[rt]) {
36         c2 (rt,rt*2,m-l+1);
37         c2 (rt,rt*2+1,r-m);
38         t2[rt]=0;
39     }
40     return ;
41 }
42 void build (int l,int r,int rt) {
43     if (l==r) {
44         scanf ("%d",&sum[rt]);
45         s[rt]=b[rt]=sum[rt];
46         return ;
47     }
48     int m=(l+r)/2;
49     build (lson);
50     build (rson);
51     pushup(rt);
52     return ;
53 }
54 void update (int L,int R,int l,int r,int rt) {
55     if (l>R||r<L) return ;
56     if (l>=L&&r<=R&&(s[rt]>100||b[rt]<=100)) {
57         if (s[rt]>100)  {
58             sum[rt]-=(r-l+1)*10;
59             s[rt]-=10; b[rt]-=10;
60             t1[rt]++;
61         }
62         else if (b[rt]<=100) {
63             sum[rt]=(r-l+1)*91;
64             s[rt]=b[rt]=91;
65             t2[rt]=1;
66         }
67         return ;
68     }
69     int m=(l+r)/2;
70     pushdown (rt,l,r);
71     update (L,R,lson);
72     update (L,R,rson);
73     pushup (rt);
74 }
75 int query (int L,int R,int l,int r,int rt) {
76     if (r<L||l>R) return 0;
77     if (l>=L&&r<=R) return sum[rt];
78     int m=(l+r)/2;
79     pushdown (rt,l,r);
80     return  query (L,R,lson)+query (L,R,rson);
81 }
82 int main ()
83 {
84     while (~scanf ("%d",&n)) {
85         memset (t1,0,sizeof(t1 ));
86         memset (t2,0,sizeof(t2));
87         build (1,n,1);
88         scanf ("%d",&q);
89         for (int i=1;i<=q;i++) {
90             int op,l,r;
91             scanf ("%d %d %d",&op,&l,&r);
92             if (op==2) printf ("%d
",query(l,r,1,n,1));
93             else       update (l,r,1,n,1);
94         }
95     }
96     return 0;
97 }
抓住青春的尾巴。。。
原文地址:https://www.cnblogs.com/xidian-mao/p/9597227.html