https://vjudge.net/contest/66989
A、敌兵布阵
单点修改、区间查询、维护区间和

1 //CSDN:https://blog.csdn.net/qq_40889820
2 #include<iostream>
3 #include<sstream>
4 #include<fstream>
5 #include<algorithm>
6 #include<cstring>
7 #include<iomanip>
8 #include<cstdlib>
9 #include<cctype>
10 #include<vector>
11 #include<string>
12 #include<cmath>
13 #include<ctime>
14 #include<stack>
15 #include<queue>
16 #include<map>
17 #include<set>
18 #define mem(a,b) memset(a,b,sizeof(a))
19 #define random(a,b) (rand()%(b-a+1)+a)
20 #define ll long long
21 #define ull unsigned long long
22 #define e 2.71828182
23 #define Pi acos(-1.0)
24 #define ls(rt) (rt<<1)
25 #define rs(rt) (rt<<1|1)
26 #define lowbit(x) (x&(-x))
27 using namespace std;
28 const int MAXN=5e4+5;
29 int a[MAXN];
30 struct node
31 {
32 int sum;
33 }T[MAXN<<2];
34 int read()
35 {
36 int s=1,x=0;
37 char ch=getchar();
38 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
39 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
40 return x*s;
41 }
42 void push_up(int p,int l,int r)
43 {
44 T[p].sum=T[ls(p)].sum+T[rs(p)].sum;
45 }
46 void build(int p,int l,int r)
47 {
48 if(l==r)
49 {
50 T[p].sum=a[l];
51 return;
52 }
53 int mid=(l+r)>>1;
54 build(ls(p),l,mid);
55 build(rs(p),mid+1,r);
56 push_up(p,l,r);
57 }
58 void update(int p,int l,int r,int lr,int k)
59 {
60 if(l==r)
61 {
62 T[p].sum+=k;
63 return;
64 }
65 int mid=(l+r)>>1;
66 if(lr<=mid) update(ls(p),l,mid,lr,k);
67 else update(rs(p),mid+1,r,lr,k);
68 push_up(p,l,r);
69 }
70 int query(int p,int l,int r,int nl,int nr)
71 {
72 if(nl<=l&&nr>=r) return T[p].sum;
73 int mid=(l+r)>>1,ans=0;
74 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr);
75 if(nr>mid) ans+=query(rs(p),mid+1,r,nl,nr);
76 return ans;
77 }
78 int main()
79 {
80 int t=read(),nl,nr,n;
81 string ord;
82 for(int cas=1;cas<=t;++cas)
83 {
84 cout<<"Case "<<cas<<":\n";
85 n=read();
86 for(int i=1;i<=n;++i)
87 a[i]=read();
88 build(1,1,n);
89 while(true)
90 {
91 cin>>ord;
92 if(ord=="End") break;
93 else if(ord=="Query")
94 {
95 nl=read(),nr=read();
96 cout<<query(1,1,n,nl,nr)<<endl;
97 }
98 else if(ord=="Add")
99 {
100 nl=read(),nr=read();
101 update(1,1,n,nl,nr);
102 }
103 else
104 {
105 nl=read(),nr=read();
106 update(1,1,n,nl,-nr);
107 }
108 }
109 }
110 return 0;
111 }
单点修改、区间查询、维护区间最大值

1 //CSDN:https://blog.csdn.net/qq_40889820
2 #include<iostream>
3 #include<sstream>
4 #include<fstream>
5 #include<algorithm>
6 #include<cstring>
7 #include<iomanip>
8 #include<cstdlib>
9 #include<cctype>
10 #include<vector>
11 #include<string>
12 #include<cmath>
13 #include<ctime>
14 #include<stack>
15 #include<queue>
16 #include<map>
17 #include<set>
18 #define mem(a,b) memset(a,b,sizeof(a))
19 #define random(a,b) (rand()%(b-a+1)+a)
20 #define ll long long
21 #define ull unsigned long long
22 #define e 2.71828182
23 #define Pi acos(-1.0)
24 #define ls(rt) (rt<<1)
25 #define rs(rt) (rt<<1|1)
26 #define lowbit(x) (x&(-x))
27 using namespace std;
28 const int MAXN=2e5+5;
29 int a[MAXN];
30 struct node
31 {
32 int maxx;
33 }T[MAXN<<2];
34 int read()
35 {
36 int s=1,x=0;
37 char ch=getchar();
38 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
39 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
40 return x*s;
41 }
42 void push_up(int p,int l,int r)
43 {
44 T[p].maxx=max(T[ls(p)].maxx,T[rs(p)].maxx);
45 }
46 void build(int p,int l,int r)
47 {
48 if(l==r)
49 {
50 T[p].maxx=a[l];
51 return;
52 }
53 int mid=(l+r)>>1;
54 build(ls(p),l,mid);
55 build(rs(p),mid+1,r);
56 push_up(p,l,r);
57 }
58 void update(int p,int l,int r,int lr,int k)
59 {
60 if(l==r)
61 {
62 T[p].maxx=k;
63 return;
64 }
65 int mid=(l+r)>>1;
66 if(lr<=mid) update(ls(p),l,mid,lr,k);
67 else update(rs(p),mid+1,r,lr,k);
68 push_up(p,l,r);
69 }
70 int query(int p,int l,int r,int nl,int nr)
71 {
72 if(nl<=l&&nr>=r) return T[p].maxx;
73 int mid=(l+r)>>1,ans=0;
74 if(nl<=mid) ans=max(query(ls(p),l,mid,nl,nr),ans);
75 if(nr>mid) ans=max(query(rs(p),mid+1,r,nl,nr),ans);
76 return ans;
77 }
78 int main()
79 {
80 int n,m;
81 while(~scanf("%d%d",&n,&m))
82 {
83 for(int i=1;i<=n;++i)
84 a[i]=read();
85 build(1,1,n);
86 char ord;
87 int A,B;
88 while(m--)
89 {
90 cin>>ord;
91 A=read(),B=read();
92 if(ord=='Q')
93 cout<<query(1,1,n,A,B)<<endl;
94 else
95 update(1,1,n,A,B);
96 }
97 }
98 return 0;
99 }
C、A Simple Problem with Integers
区间修改、区间查询、维护区间和、延迟标记

1 //CSDN:https://blog.csdn.net/qq_40889820
2 #include<iostream>
3 #include<sstream>
4 #include<fstream>
5 #include<algorithm>
6 #include<cstring>
7 #include<iomanip>
8 #include<cstdlib>
9 #include<cctype>
10 #include<vector>
11 #include<string>
12 #include<cmath>
13 #include<ctime>
14 #include<stack>
15 #include<queue>
16 #include<map>
17 #include<set>
18 #define mem(a,b) memset(a,b,sizeof(a))
19 #define random(a,b) (rand()%(b-a+1)+a)
20 #define ll long long
21 #define ull unsigned long long
22 #define e 2.71828182
23 #define Pi acos(-1.0)
24 #define ls(rt) (rt<<1)
25 #define rs(rt) (rt<<1|1)
26 #define lowbit(x) (x&(-x))
27 using namespace std;
28 const int MAXN=1e5+5;
29 ll a[MAXN];
30 struct node
31 {
32 ll sum,tag;
33 }T[MAXN<<2];
34 ll read()
35 {
36 ll s=1,x=0;
37 char ch=getchar();
38 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
39 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
40 return x*s;
41 }
42 void push_up(int p,int l,int r)
43 {
44 T[p].sum=T[ls(p)].sum+T[rs(p)].sum;
45 }
46 void build(int p,int l,int r)
47 {
48 if(l==r)
49 {
50 T[p].sum=a[l];
51 return;
52 }
53 T[p].tag=0;
54 int mid=(l+r)>>1;
55 build(ls(p),l,mid);
56 build(rs(p),mid+1,r);
57 push_up(p,l,r);
58 }
59 void push_down(int p,int l,int r)
60 {
61 if(!T[p].tag) return;
62 T[ls(p)].tag+=T[p].tag,T[rs(p)].tag+=T[p].tag;
63 int mid=(l+r)>>1;
64 T[ls(p)].sum+=T[p].tag*(mid-l+1);
65 T[rs(p)].sum+=T[p].tag*(r-mid);
66 T[p].tag=0;
67 }
68 void update(int p,int l,int r,int nl,int nr,ll k)
69 {
70 if(nl<=l&&nr>=r)
71 {
72 T[p].sum+=k*(r-l+1);
73 T[p].tag+=k;
74 return ;
75 }
76 push_down(p,l,r);
77 int mid=(l+r)>>1;
78 if(nl<=mid) update(ls(p),l,mid,nl,nr,k);
79 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k);
80 push_up(p,l,r);
81 }
82 ll query(int p,int l,int r,int nl,int nr)
83 {
84 if(nl<=l&&nr>=r) return T[p].sum;
85 push_down(p,l,r);
86 int mid=(l+r)>>1;
87 ll ans=0;
88 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr);
89 if(nr>mid) ans+=query(rs(p),mid+1,r,nl,nr);
90 return ans;
91 }
92 int main()
93 {
94 int n=read(),m=read();
95 for(int i=1;i<=n;++i)
96 a[i]=read();
97 build(1,1,n);
98 char ord;
99 int A,B;
100 ll C;
101 while(m--)
102 {
103 cin>>ord;
104 A=read(),B=read();
105 if(ord=='Q')
106 cout<<query(1,1,n,A,B)<<endl;
107 else
108 {
109 C=read();
110 update(1,1,n,A,B,C);
111 }
112 }
113 return 0;
114 }

区间问题,后来的能把先来的覆盖,问最后有多少种。
区间修改、区间查询(一次)、维护区间最大值(最后查询只需查询叶子结点,这个有没有无所谓其实)
用到了区间离散化,离散化的另一种形式(理解这个花了不少时间),这里特殊的是排序后距离大于1便增加一个点,详见代码

1 #include<stdio.h>
2 #include<cstring>
3 #include<iostream>
4 #include<algorithm>
5 #define ls(p) (p<<1)
6 #define rs(p) (p<<1|1)
7 using namespace std;
8 const int MAXN=4e4+5;//原先是1e4,普通离散化后2倍,特殊后也要2倍以防万一
9 struct node
10 {
11 int big,tag;//最大序号即上层的post、懒标记同记录post编号
12 }T[MAXN<<2];
13 int book[MAXN],Hash[MAXN];
14 int L[MAXN],R[MAXN];
15 void push_up(int p)
16 {
17 T[p].big=max(T[ls(p)].big,T[rs(p)].big);
18 }
19 void push_down(int p,int l,int r)
20 {
21 if(!T[p].tag) return;
22 int mid=(l+r)>>1;
23 T[ls(p)].tag=max(T[p].tag,T[ls(p)].tag);
24 T[rs(p)].tag=max(T[p].tag,T[rs(p)].tag);
25 T[ls(p)].big=max(T[p].tag,T[ls(p)].tag);
26 T[rs(p)].big=max(T[p].tag,T[rs(p)].big);
27 T[p].tag=0;
28 }
29 void build(int p,int l,int r)
30 {
31 if(l==r)
32 {
33 T[p].big=0,T[p].tag=0;
34 return ;
35 }
36 T[p].big=0,T[p].tag=0;
37 int mid=(l+r)>>1;
38 build(ls(p),l,mid);
39 build(rs(p),mid+1,r);
40 push_up(p);
41 }
42 void update(int p,int l,int r,int nl,int nr,int k)
43 {
44 if(nl<=l&&nr>=r)
45 {
46 T[p].big=max(T[p].big,k);//其实多此一举,反正更新的时候k从小到大
47 T[p].tag=max(T[p].tag,k);//同上
48 return;
49 }
50 push_down(p,l,r);
51 int mid=(l+r)>>1;
52 if(nl<=mid) update(ls(p),l,mid,nl,nr,k);
53 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k);
54 push_up(p);
55 }
56 int query(int p,int l,int r,int nl,int nr)
57 {
58 if(l==r)//统计叶子节点的
59 {
60 if(T[p].big&&!book[T[p].big])
61 {
62 book[T[p].big]=1;
63 return 1;
64 }
65 return 0;
66 }
67 int ans=0,mid=(l+r)>>1;
68 push_down(p,l,r);
69 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr);
70 if(nr>mid) ans+=query(rs(p),mid+1,r,nl,nr);
71 return ans;
72 }
73 int read()
74 {
75 int s=1,x=0;char ch=getchar();
76 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
77 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
78 return s*x;
79 }
80 int main()
81 {
82 int test=read();
83 while(test--)
84 {
85 int n=read();
86 for(int i=1;i<=n;++i)
87 {
88 L[i]=read(),R[i]=read();
89 Hash[(i<<1)-1]=L[i],Hash[i<<1]=R[i];
90 }
91 sort(Hash+1,Hash+2*n+1);
92
93 int tot=unique(Hash+1,Hash+2*n+1)-Hash-1,tmp=tot;//去重
94 for(int i=2;i<=tot;++i)
95 if(Hash[i]-Hash[i-1]>1) Hash[++tmp]=Hash[i-1]+1;//相邻两个点的距离大于1则新加一个点
96 tot=tmp;//离散化后最多tot个点
97 sort(Hash+1,Hash+tot+1);
98 build(1,1,tot);memset(book,0,sizeof(book));
99 for(int i=1;i<=n;++i)
100 {
101 int l=lower_bound(Hash+1,Hash+tot+1,L[i])-Hash;
102 int r=lower_bound(Hash+1,Hash+tot+1,R[i])-Hash;
103 update(1,1,tot,l,r,i);//i代表颜色编号
104 }
105 cout<<query(1,1,tot,1,tot)<<endl;
106 }
107 }
去除冗余操作后代码:

1 #include<stdio.h>
2 #include<cstring>
3 #include<iostream>
4 #include<algorithm>
5 #define ls(p) (p<<1)
6 #define rs(p) (p<<1|1)
7 using namespace std;
8 const int MAXN=4e4+5;//原先是1e4,普通离散化后2倍,特殊后也要2倍以防万一
9 struct node
10 {
11 int tag;
12 }T[MAXN<<2];
13 int book[MAXN],Hash[MAXN];
14 int L[MAXN],R[MAXN];
15 void push_down(int p,int l,int r)
16 {
17 if(!T[p].tag) return;
18 int mid=(l+r)>>1;
19 T[ls(p)].tag=T[p].tag;
20 T[rs(p)].tag=T[p].tag;
21 T[p].tag=0;
22 }
23 void update(int p,int l,int r,int nl,int nr,int k)
24 {
25 if(nl<=l&&nr>=r)
26 {
27 T[p].tag=k;//同上
28 return;
29 }
30 push_down(p,l,r);
31 int mid=(l+r)>>1;
32 if(nl<=mid) update(ls(p),l,mid,nl,nr,k);
33 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k);
34 }
35 int query(int p,int l,int r,int nl,int nr)
36 {
37 if(l==r)//统计叶子节点的
38 {
39 if(T[p].tag&&!book[T[p].tag])
40 {
41 book[T[p].tag]=1;
42 return 1;
43 }
44 return 0;
45 }
46 int ans=0,mid=(l+r)>>1;
47 push_down(p,l,r);
48 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr);
49 if(nr>mid) ans+=query(rs(p),mid+1,r,nl,nr);
50 return ans;
51 }
52 int read()
53 {
54 int s=1,x=0;char ch=getchar();
55 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
56 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
57 return s*x;
58 }
59 int main()
60 {
61 int test=read();
62 while(test--)
63 {
64 int n=read();
65 for(int i=1;i<=n;++i)
66 {
67 L[i]=read(),R[i]=read();
68 Hash[(i<<1)-1]=L[i],Hash[i<<1]=R[i];
69 }
70 sort(Hash+1,Hash+2*n+1);
71
72 int tot=unique(Hash+1,Hash+2*n+1)-Hash-1,tmp=tot;//去重
73 for(int i=2;i<=tot;++i)
74 if(Hash[i]-Hash[i-1]>1) Hash[++tmp]=Hash[i-1]+1;//相邻两个点的距离大于1则新加一个点
75 tot=tmp;//离散化后最多tot个点
76 sort(Hash+1,Hash+tot+1);
77 memset(T,0,sizeof(T));memset(book,0,sizeof(book));
78 for(int i=1;i<=n;++i)
79 {
80 int l=lower_bound(Hash+1,Hash+tot+1,L[i])-Hash;
81 int r=lower_bound(Hash+1,Hash+tot+1,R[i])-Hash;
82 update(1,1,tot,l,r,i);//i代表颜色编号
83 }
84 cout<<query(1,1,tot,1,tot)<<endl;
85 }
86 }
区间修改(改成特定的值)、区间查询(总区间、一次)

1 #include<bits/stdc++.h>
2 #define ls(rt) (rt<<1)
3 #define rs(rt) (rt<<1|1)
4 using namespace std;
5 const int MAXN=1e5+5;
6 struct node
7 {
8 int sum,tag;
9 }T[MAXN<<2];
10 void push_up(int p)
11 {
12 T[p].sum=T[ls(p)].sum+T[rs(p)].sum;
13 }
14 void build(int p,int l,int r)
15 {
16 if(l==r)
17 {
18 T[p].tag=0;
19 T[p].sum=1;
20 return;
21 }
22 T[p].tag=0,T[p].sum=0;
23 int mid=(l+r)>>1;
24 build(ls(p),l,mid);
25 build(rs(p),mid+1,r);
26 push_up(p);
27 }
28 void push_down(int p,int l,int r)
29 {
30 if(!T[p].tag) return ;
31 T[ls(p)].tag=T[p].tag;
32 T[rs(p)].tag=T[p].tag;
33 int mid=(l+r)>>1;
34 T[ls(p)].sum=T[p].tag*(mid-l+1);
35 T[rs(p)].sum=T[p].tag*(r-mid);
36 T[p].tag=0;
37 }
38 void update(int p,int l,int r,int nl,int nr,int k)
39 {
40 if(nl<=l&&nr>=r)
41 {
42 T[p].tag=k;
43 T[p].sum=(r-l+1)*k;
44 return;
45 }
46 push_down(p,l,r);
47 int mid=(l+r)>>1;
48 if(nl<=mid) update(ls(p),l,mid,nl,nr,k);
49 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k);
50 push_up(p);
51 }
52 int query(int p,int l,int r,int nl,int nr)
53 {
54 if(nl<=l&&nr<=r) return T[p].sum;
55 int ans=0,mid=(l+r)>>1;
56 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr);
57 if(nr>mid) ans+=query(rs(p),mid+1,r,nl,nr);
58 return ans;
59 }
60 int read()
61 {
62 int s=1,x=0;char ch=getchar();
63 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
64 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
65 return s*x;
66 }
67 int main()
68 {
69 int test=read(),x,y,z;
70 for(int i=1;i<=test;++i)
71 {
72 int n=read();
73 build(1,1,n);
74 int q=read();
75 while(q--)
76 {
77 x=read(),y=read(),z=read();
78 update(1,1,n,x,y,z);
79 }
80 cout<<"Case "<<i<<": ";
81 cout<<"The total value of the hook is ";
82 cout<<query(1,1,n,1,n)<<".\n";
83 }
84 }
区间修改(改成特定的值)、区间查询(总区间、一次)
这题特殊的是,在[a,b]区间内染色实际上是在第a+1、a+2、...、b个区间内染色,即线段树的第a个叶子结点维护的是[a,a+1](即第a个)区间的染色情况。
要从左往右遍历叶子结点,实际上和先序遍历得到的叶子结点顺序一样。

1 #include<iostream>
2 #include<sstream>
3 #include<fstream>
4 #include<algorithm>
5 #include<cstring>
6 #include<iomanip>
7 #include<cstdlib>
8 #include<cctype>
9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 const int MAXN=8e3+5;
28 int x1[MAXN],x2[MAXN],c[MAXN];
29 int color[MAXN];
30 struct node
31 {
32 int tag;
33 }T[MAXN<<2];
34 int n;
35 int read()
36 {
37 int s=1,x=0;
38 char ch=getchar();
39 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
40 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
41 return x*s;
42 }
43 void build(int p,int l,int r)
44 {
45 if(l==r)
46 {
47 T[p].tag=-1;
48 return;
49 }
50 T[p].tag=-1;
51 int mid=(l+r)>>1;
52 build(ls(p),l,mid);
53 build(rs(p),mid+1,r);
54 }
55 void push_down(int p,int l,int r)
56 {
57 if(T[p].tag==-1) return;
58 T[ls(p)].tag=T[p].tag;
59 T[rs(p)].tag=T[p].tag;
60 T[p].tag=-1;
61 }
62 void update(int p,int l,int r,int nl,int nr,int k)
63 {
64 if(nl<=l&&nr>=r)
65 {
66 T[p].tag=k;
67 return;
68 }
69 int mid=(l+r)>>1;
70 push_down(p,l,r);
71 if(nl<=mid) update(ls(p),l,mid,nl,nr,k);
72 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k);
73
74 }
75 vector<int> buf;
76 void query(int p,int l,int r)
77 {
78 if(l==r)
79 {
80 buf.push_back(T[p].tag);
81 return;
82 }
83 push_down(p,l,r);
84 int mid=(l+r)>>1;
85 query(ls(p),l,mid);
86 query(rs(p),mid+1,r);
87 }
88 /*int last;
89 void query(int p,int l,int r)
90 {
91 if(l==r)
92 {
93 if(T[p].tag!=-1&&T[p].tag!=last)
94 {
95 color[T[p].tag]++;
96 }
97 last=T[p].tag;
98 return;
99 }
100 push_down(p,l,r);
101 int mid=(l+r)>>1;
102 query(ls(p),l,mid);
103 query(rs(p),mid+1,r);
104 }*/
105 int main()
106 {
107 while(~scanf("%d",&n))
108 {
109 //last=-1;
110 int tot=-1,mxc=-1;
111 buf.clear();
112 mem(color,0);
113 for(int i=1;i<=n;++i)
114 x1[i]=read()+1,x2[i]=read(),c[i]=read(),
115 tot=max(tot,x2[i]),mxc=max(mxc,c[i]);
116
117 build(1,1,tot);
118
119 for(int i=1;i<=n;++i)
120 update(1,1,tot,x1[i],x2[i],c[i]);
121
122 query(1,1,tot);
123
124 if(buf[0]!=-1) color[buf[0]]++;
125 for(int i=1;i<tot;++i)
126 {
127 if(buf[i]==-1) continue;
128 if(buf[i]==buf[i-1]) continue;
129 else color[buf[i]]++;
130 }
131 //for(int i=0;i<tot;++i) cout<<buf[i]<<' ';cout<<endl;
132
133 for(int i=0;i<=mxc;++i)
134 if(color[i]) cout<<i<<' '<<color[i]<<"\n";
135 cout<<endl;
136 }
137 return 0;
138 }

1 #include<iostream>
2 #include<sstream>
3 #include<fstream>
4 #include<algorithm>
5 #include<cstring>
6 #include<iomanip>
7 #include<cstdlib>
8 #include<cctype>
9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 const int MAXN=8e3+5;
28 int x1[MAXN],x2[MAXN],c[MAXN];
29 int color[MAXN];
30 struct node
31 {
32 int tag;
33 }T[MAXN<<2];
34 int n;
35 int read()
36 {
37 int s=1,x=0;
38 char ch=getchar();
39 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
40 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
41 return x*s;
42 }
43 void build(int p,int l,int r)
44 {
45 if(l==r)
46 {
47 T[p].tag=-1;
48 return;
49 }
50 T[p].tag=-1;
51 int mid=(l+r)>>1;
52 build(ls(p),l,mid);
53 build(rs(p),mid+1,r);
54 }
55 void push_down(int p,int l,int r)
56 {
57 if(T[p].tag==-1) return;
58 T[ls(p)].tag=T[p].tag;
59 T[rs(p)].tag=T[p].tag;
60 T[p].tag=-1;
61 }
62 void update(int p,int l,int r,int nl,int nr,int k)
63 {
64 if(nl<=l&&nr>=r)
65 {
66 T[p].tag=k;
67 return;
68 }
69 int mid=(l+r)>>1;
70 push_down(p,l,r);
71 if(nl<=mid) update(ls(p),l,mid,nl,nr,k);
72 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k);
73
74 }
75 vector<int> buf;
76 void query(int p,int l,int r,int nl,int nr)
77 {
78 if(l==r)
79 {
80 buf.push_back(T[p].tag);
81 return;
82 }
83 push_down(p,l,r);
84 int mid=(l+r)>>1;
85 if(nl<=mid) query(ls(p),l,mid,nl,nr);
86 if(nr>mid) query(rs(p),mid+1,r,nl,nr);
87 }
88 int main()
89 {
90 while(~scanf("%d",&n))
91 {
92 int tot=-1,mxc=-1;
93 buf.clear();
94 mem(color,0);
95 for(int i=1;i<=n;++i)
96 x1[i]=read()+1,x2[i]=read(),c[i]=read(),
97 tot=max(tot,x2[i]),mxc=max(mxc,c[i]);
98
99 build(1,1,tot);
100
101 for(int i=1;i<=n;++i)
102 update(1,1,tot,x1[i],x2[i],c[i]);
103
104 query(1,1,tot,1,tot);
105
106 if(buf[0]!=-1) color[buf[0]]++;
107 for(int i=1;i<tot;++i)
108 {
109 if(buf[i]==-1) continue;
110 if(buf[i]==buf[i-1]) continue;
111 else color[buf[i]]++;
112 }
113 //for(int i=0;i<tot;++i) cout<<buf[i]<<' ';cout<<endl;
114
115 for(int i=0;i<=mxc;++i)
116 if(color[i]) cout<<i<<' '<<color[i]<<"\n";
117 cout<<endl;
118 }
119 }
区间查询最大最小值

1 #include<iostream>
2 #include<stdio.h>
3 #include<algorithm>
4 #define ls(p) (p<<1)
5 #define rs(p) (p<<1|1)
6 using namespace std;
7 const int MAXN=5e4+5;
8 int a[MAXN];
9 struct node
10 {
11 int big,small;
12 }T[MAXN<<2];
13 void push_up(int p)
14 {
15 T[p].big=max(T[ls(p)].big,T[rs(p)].big);
16 T[p].small=min(T[ls(p)].small,T[rs(p)].small);
17 }
18 void build(int p,int l,int r)
19 {
20 if(l==r)
21 {
22 T[p].big=T[p].small=a[l];
23 return;
24 }
25 T[p].big=-1,T[p].small=0x7fffffff;
26 int mid=(l+r)>>1;
27 build(ls(p),l,mid);
28 build(rs(p),mid+1,r);
29 push_up(p);
30 }
31 int query_big(int p,int l,int r,int nl,int nr)
32 {
33 if(nl<=l&&nr>=r) return T[p].big;
34 int ans=-1,mid=(l+r)>>1;
35 if(nl<=mid) ans=max(ans,query_big(ls(p),l,mid,nl,nr));
36 if(nr>mid) ans=max(ans,query_big(rs(p),mid+1,r,nl,nr));
37 return ans;
38 }
39 int query_small(int p,int l,int r,int nl,int nr)
40 {
41 if(nl<=l&&nr>=r) return T[p].small;
42 int ans=0x7fffffff,mid=(l+r)>>1;
43 if(nl<=mid) ans=min(ans,query_small(ls(p),l,mid,nl,nr));
44 if(nr>mid) ans=min(ans,query_small(rs(p),mid+1,r,nl,nr));
45 return ans;
46 }
47 int read()
48 {
49 int x=0,s=1;char ch=getchar();
50 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
51 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
52 return x*s;
53 }
54 int main()
55 {
56 int n=read(),q=read();
57 for(int i=1;i<=n;++i) a[i]=read();
58 build(1,1,n);
59 while(q--)
60 {
61 int L=read(),R=read();
62 cout<<query_big(1,1,n,L,R)-query_small(1,1,n,L,R)<<"\n";
63 }
64 return 0;
65 }
H、Can you answer these queries?
区间修改是区间中的每个元素开平方,无法通过push_down操作,只能对叶子结点一个一个开平方,如果单单这样是会超时的,注意到开平方时数据大小衰减得很快,最少降到1,可以利用这一点进行剪枝。
还有个很坑的是,题中所给的x,y并未给定相对大小,注意一下

1 #include<iostream>
2 #include<stdio.h>
3 #include<algorithm>
4 #include<cmath>
5 #define ls(p) (p<<1)
6 #define rs(p) (p<<1|1)
7 #define ll long long
8 using namespace std;
9 const int MAXN=1e5+5;
10 ll a[MAXN];
11 struct node
12 {
13 ll sum;
14 }T[MAXN<<2];
15 void push_up(int p)
16 {
17 T[p].sum=T[ls(p)].sum+T[rs(p)].sum;
18 }
19 void build(int p,int l,int r)
20 {
21 if(l==r)
22 {
23 T[p].sum=a[l];
24 return;
25 }
26 T[p].sum=0;
27 int mid=(l+r)>>1;
28 build(ls(p),l,mid);
29 build(rs(p),mid+1,r);
30 push_up(p);
31 }
32 void update(int p,int l,int r,int nl,int nr)
33 {
34 if(T[p].sum==(r-l+1)) return;
35 if(l==r)
36 {
37 T[p].sum=sqrt(T[p].sum);
38 return;
39 }
40 int mid=(l+r)>>1;
41 if(nl<=mid) update(ls(p),l,mid,nl,nr);
42 if(nr>mid) update(rs(p),mid+1,r,nl,nr);
43 push_up(p);
44 }
45 ll query(int p,int l,int r,int nl,int nr)
46 {
47 if(nl<=l&&nr>=r) return T[p].sum;
48 ll ans=0;int mid=(l+r)>>1;
49 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr);
50 if(nr>mid) ans+=query(rs(p),mid+1,r,nl,nr);
51 return ans;
52 }
53 ll read()
54 {
55 ll x=0,s=1;char ch=getchar();
56 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
57 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
58 return x*s;
59 }
60 int main()
61 {
62 int n,q,t,x,y,cnt=0;
63 while(~scanf("%d",&n))
64 {
65 cout<<"Case #"<<++cnt<<":\n";
66 for(int i=1;i<=n;++i) a[i]=read();
67 build(1,1,n);
68 q=read();
69 while(q--)
70 {
71 t=read(),x=read(),y=read();
72 if(x>y) swap(x,y);//这题这里恶心
73 if(t) cout<<query(1,1,n,x,y)<<"\n";
74 else update(1,1,n,x,y);
75 }
76 cout<<endl;
77 }
78 return 0;
79 }
找最大连续区间
维护最长前缀、最长后缀、最长连续区间
HDU有毒吧,有两个输入输出方面的bug调了我一上午
一个是关了同步后,用C++的cout输出,一直是个Output Limit Exceeded
另一个是C的scanf读char,真的是,回车都读进去了,改成char型数组过了
对了,这题有两个思路:
一个是就如上所说,求最大连续区间。(就是这个,没用快读,找了一早上的bug)

1 #include<bits/stdc++.h>
2 #define ls(p) (p<<1)
3 #define rs(p) (p<<1|1)
4 using namespace std;
5 const int MAXN=5e4+5;
6 struct node
7 {
8 int pre,suf,maxlen;//左边连续最长、右边连续最长、最长
9 }T[MAXN<<2];
10 void push_up(int p,int l,int r)
11 {
12 int mid=(l+r)>>1;
13 T[p].pre= T[ls(p)].pre==mid-l+1? T[ls(p)].pre+T[rs(p)].pre : T[ls(p)].pre;
14 T[p].suf= T[rs(p)].suf==r-mid? T[rs(p)].suf+T[ls(p)].suf : T[rs(p)].suf;
15 T[p].maxlen= max( max(T[ls(p)].maxlen,T[rs(p)].maxlen), T[ls(p)].suf+T[rs(p)].pre );
16 }
17 void build(int p,int l,int r)
18 {
19 if(l==r)
20 {
21 T[p].maxlen=T[p].pre=T[p].suf=1;
22 return;
23 }
24 int mid=(l+r)>>1;
25 build(ls(p),l,mid);
26 build(rs(p),mid+1,r);
27 push_up(p,l,r);
28 }
29 void update(int p,int l,int r,int lr,int k)
30 {
31 if(l==r)
32 {
33 T[p].maxlen=T[p].pre=T[p].suf=k;
34 return;
35 }
36 int mid=(l+r)>>1;
37 if(lr<=mid) update(ls(p),l,mid,lr,k);
38 else update(rs(p),mid+1,r,lr,k);
39 push_up(p,l,r);
40 }
41 int query(int p,int l,int r,int lr)
42 {
43 if(l==r||T[p].maxlen==r-l+1||T[p].maxlen==0) return T[p].maxlen;
44 int mid=(l+r)>>1;
45 if(lr<=mid)
46 {
47 if(mid-lr+1<=T[ls(p)].suf) return query(ls(p),l,mid,lr)+T[rs(p)].pre;
48 else return query(ls(p),l,mid,lr);
49 }
50 else
51 {
52 if(lr-mid<=T[rs(p)].pre) return T[ls(p)].suf+query(rs(p),mid+1,r,lr);
53 else return query(rs(p),mid+1,r,lr);
54 }
55 }
56 int main()
57 {
58 int n,m,x;
59 char ord[10];
60 stack<int> buf;
61 while(~scanf("%d%d",&n,&m))
62 {
63 build(1,1,n);
64 while(!buf.empty()) buf.pop();
65 for(int i=1;i<=m;++i)
66 {
67 scanf("%s",ord);
68 if(ord[0]=='D')
69 {
70 scanf("%d",&x);
71 buf.push(x);
72 update(1,1,n,x,0);
73 }
74 else if(ord[0]=='R')
75 {
76 if(!buf.empty())
77 {
78 x=buf.top();
79 buf.pop();
80 update(1,1,n,x,1);
81 }
82 }
83 else if(ord[0]=='Q')
84 {
85 scanf("%d",&x);
86 printf("%d\n",query(1,1,n,x));
87 }
88 }
89 }
90 return 0;
91 }
92 /*
93 7 9
94 D 3
95 D 6
96 D 5
97 Q 4
98 Q 5
99 R
100 Q 4
101 R
102 Q 4
103 */
另一个思路比较巧妙,找最大连续区间,就是找出左端最大的不满足的端点和右端最小的不满足的端点。

1 #include<iostream>
2 #include<sstream>
3 #include<fstream>
4 #include<algorithm>
5 #include<cstring>
6 #include<iomanip>
7 #include<cstdlib>
8 #include<cctype>
9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 const int MAXN=5e4+5;
28 //const int INF=0x7fffffff;
29 struct node
30 {
31 int big,small;
32 }T[MAXN<<2];
33 stack<int> buf;
34 int n,m,x;
35 /*void push_up(int p)
36 {
37 T[p].big=max(T[ls(p)].big,T[rs(p)].big);
38 T[p].small=min(T[ls(p)].small,T[rs(p)].small);
39 }*/
40 /*void show1(int p,int l,int r)
41 {
42 if(l==r)
43 {
44 cout<<T[p].big<<' ';
45 return;
46 }
47 int mid=(l+r)>>1;
48 show1(ls(p),l,mid);
49 show1(rs(p),mid+1,r);
50 }
51 void show2(int p,int l,int r)
52 {
53 if(l==r)
54 {
55 cout<<T[p].small<<' ';
56 return;
57 }
58 int mid=(l+r)>>1;
59 show2(ls(p),l,mid);
60 show2(rs(p),mid+1,r);
61 }*/
62 void build(int p,int l,int r)
63 {
64 if(l==r)
65 {
66 T[p].big=0,T[p].small=n+1;
67 return;
68 }
69 T[p].big=0,T[p].small=n+1;
70 int mid=(l+r)>>1;
71 build(ls(p),l,mid);
72 build(rs(p),mid+1,r);
73 }
74 void update_max(int p,int l,int r,int lr,int k)
75 {
76 if(l==r)
77 {
78 T[p].big=k;
79 return;
80 }
81 int mid=(l+r)>>1;
82 if(lr<=mid) update_max(ls(p),l,mid,lr,k);
83 else update_max(rs(p),mid+1,r,lr,k);
84 T[p].big=max(T[ls(p)].big,T[rs(p)].big);
85 }
86 void update_min(int p,int l,int r,int lr,int k)
87 {
88 if(l==r)
89 {
90 T[p].small=k;
91 return;
92 }
93 int mid=(l+r)>>1;
94 if(lr<=mid) update_min(ls(p),l,mid,lr,k);
95 else update_min(rs(p),mid+1,r,lr,k);
96 T[p].small=min(T[ls(p)].small,T[rs(p)].small);
97 }
98 int query_max(int p,int l,int r,int nl,int nr)
99 {
100 if(nl<=l&&nr>=r) return T[p].big;
101 int mid=(l+r)>>1,ans=0;
102 if(nl<=mid) ans=max(ans,query_max(ls(p),l,mid,nl,nr));
103 if(nr>mid) ans=max(ans,query_max(rs(p),mid+1,r,nl,nr));
104 return ans;
105 }
106 int query_min(int p,int l,int r,int nl,int nr)
107 {
108 if(nl<=l&&nr>=r) return T[p].small;
109 int mid=(l+r)>>1,ans=n+1;
110 if(nl<=mid) ans=min(ans,query_min(ls(p),l,mid,nl,nr));
111 if(nr>mid) ans=min(ans,query_min(rs(p),mid+1,r,nl,nr));
112 return ans;
113 }
114 int read()
115 {
116 int s=1,x=0;
117 char ch=getchar();
118 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
119 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
120 return x*s;
121 }
122 int main()
123 {
124 while(~scanf("%d%d",&n,&m))
125 {
126 char ord;
127 build(1,1,n);
128 while(!buf.empty()) buf.pop();
129 while(m--)
130 {
131 cin>>ord;
132 if(ord=='D')
133 {
134 x=read();
135 buf.push(x);
136 update_max(1,1,n,x,x);
137 update_min(1,1,n,x,x);
138 }
139 else if(ord=='R')
140 {
141 if(buf.empty()) exit(-1);
142 x=buf.top();buf.pop();
143 update_max(1,1,n,x,0);
144 update_min(1,1,n,x,n+1);
145 }
146 else if(ord=='Q')
147 {
148 x=read();
149 int Lmax=query_max(1,1,n,1,x),Rmin=query_min(1,1,n,x,n);
150 if(Lmax==Rmin) cout<<"0\n";
151 else cout<<Rmin-Lmax-1<<"\n";
152 }
153 }
154 }
155 return 0;
156 }

DFS序

1 #include<bits/stdc++.h>
2 #define ls(p) (p<<1)
3 #define rs(p) (p<<1|1)
4 using namespace std;
5 const int MAXN=2e5+5;
6 vector<int> G[MAXN];
7 int l[MAXN],r[MAXN];
8 int root[MAXN];
9 int n,m,u,v;
10 int cnt;
11 struct node
12 {
13 int tag;
14 }T[MAXN<<2];
15 void build(int p,int l,int r)
16 {
17 T[p].tag=-1;
18 if(l==r) return;
19 int mid=(l+r)>>1;
20 build(ls(p),l,mid);
21 build(rs(p),mid+1,r);
22 }
23 void push_down(int p)
24 {
25 if(T[p].tag==-1) return;
26 T[ls(p)].tag=T[p].tag;
27 T[rs(p)].tag=T[p].tag;
28 T[p].tag=-1;
29 }
30 void update(int p,int l,int r,int nl,int nr,int k)
31 {
32 if(nl<=l&&nr>=r)
33 {
34 T[p].tag=k;
35 return;
36 }
37 int mid=(l+r)>>1;
38 push_down(p);
39 if(nl<=mid) update(ls(p),l,mid,nl,nr,k);
40 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k);
41 }
42 int query(int p,int l,int r,int lr)
43 {
44 if(l==r) return T[p].tag;
45 int mid=(l+r)>>1;
46 push_down(p);
47 if(lr<=mid) return query(ls(p),l,mid,lr);
48 else return query(rs(p),mid+1,r,lr);
49 }
50 int read()
51 {
52 int x=0,s=1;char ch=getchar();
53 while(!isdigit(ch)){if(ch=='-') s=-1;ch=getchar();}
54 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
55 return x*s;
56 }
57 void dfs(int p)
58 {
59 l[p]=++cnt;
60 for(int i=0;i<G[p].size();++i)
61 dfs(G[p][i]);
62 r[p]=cnt;
63 }
64 int main()
65 {
66 int cas=read(),x,y;
67 char c[10];
68 for(int j=1;j<=cas;++j)
69 {
70 cout<<"Case #"<<j<<":\n";
71 n=read();
72 memset(root,0,sizeof(root));
73 for(int i=1;i<=n-1;++i)
74 {
75 u=read(),v=read();
76 G[v].push_back(u);
77 root[u]=1;
78 }
79 cnt=0;
80 for(int i=1;i<=n;++i)
81 if(!root[i]) dfs(i);
82
83 /*for(int i=1;i<=n;++i)
84 cout<<l[i]<<' '<<r[i]<<endl;*/
85 build(1,1,n);
86 m=read();
87 while(m--)
88 {
89 scanf("%s",c);
90 if(c[0]=='C')
91 {
92 x=read();
93 cout<<query(1,1,n,l[x])<<"\n";
94 }
95 else if(c[0]=='T')
96 {
97 x=read(),y=read();
98 update(1,1,n,l[x],r[x],y);
99 }
100 }
101
102 for(int i=1;i<=n;++i) G[i].clear();
103 }
104 return 0;
105 }
来源:https://www.cnblogs.com/wangzhebufangqi/p/11337102.html
