K - Party HDU - 6521 (线段树)
题目链接“
K - Party
题目大意:n个人排成一列,一开始他们互不认识,每次选[l,r]上的人开party,使他们互相认识,求出每次party之后新互相认识的人的对数。
具体思路:一个人,认识的人是连续的,所以我们维护一个人的最远能到达的R.所以每一段区间我们维护这个区间能到的最短的距离。
AC代码:
1 #include<iostream>
2 #include<stdio.h>
3 #include<cmath>
4 #include<string>
5 #include<algorithm>
6 using namespace std;
7 # define ll long long
8 # define inf 0x3f3f3f3f
9 # define lson l,mid,rt<<1
10 # define rson mid+1,r,rt<<1|1
11 const int maxn = 2e6+100;
12 const int mod = 1e9;
13 int tree[maxn];
14 void up(int rt)
15 {
16 tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
17 }
18 void buildtree(int l,int r,int rt)
19 {
20 tree[rt]=0;
21 if(l==r)
22 {
23 tree[rt]=l;
24 return ;
25 }
26 int mid=l+r>>1;
27 buildtree(lson);
28 buildtree(rson);
29 up(rt);
30 }
31 int ans;
32 void update(int l,int r,int rt,int L,int R)
33 {
34 if(R<l||L>r||tree[rt]>R)
35 return ;
36 if(l==r)
37 {
38 ans+=(R-tree[rt]);
39 tree[rt]=R;
40 return ;
41 }
42 int mid=l+r>>1;
43 update(lson,L,R);
44 update(rson,L,R);
45 up(rt);
46 }
47 int main()
48 {
49 int n,m;
50 while(~scanf("%d %d",&n,&m))
51 {
52 int st,ed;
53 buildtree(1,n,1);
54 for(int i=1; i<=m; i++)
55 {
56 scanf("%d %d",&st,&ed);
57 ans=0;
58 update(1,n,1,st,ed);
59 printf("%d\n",ans);
60 }
61 }
62 return 0;
63 }