Fork me on GitHub

TLS 9.2 A&B

TLS 9.2A

这其实是[HNOI2006]鬼谷子的钱袋对叭…

然后你就考虑二进制是咋做到完美表示任意一个十进制数字的.

你看看它二进制下有多少位就行了.

TLS 9.2B

由于$T1$太水了,所以我决定把它和$T2$放一起.

这题水的不行…我们当场想出了一堆做法,包括但不限于线段树,左端点排序暴力染色,并查集,差分.

我一开始写了线段树写$RE$了,然后我毅然决然地选择了差分.

先讲线段树:

你就每次区间修改,最后像建树一样再把叶子的值赋值回去,再扫一遍就行了.
注意:线段树建树的复杂度是$O(n)$的.

然后是左端点排序暴力染色:

把所有询问读进来,按左端点排序,从左向右染色就行了,最后也要再扫一遍.

然后是并查集:

你令并查集数组$f_i$表示$i$这个点向右第一个被染过色的节点的位置,然后路径压缩,每次跳并查集就行了,这是并查集的基操,应该大多数学过并查集的人都会.

最后是最简单的差分:

因为你只关心最后是$0$的区间,所以每次来一个操作你就直接差分$O(1)$修改最后前缀和求出修改完的数组,再扫一遍就行了.

只给差分的代码,因为我只留了差分的代码:

$Code:$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#define MEM(x,y) memset ( x , y , sizeof ( x ) )
#define rep(i,a,b) for (int i = a ; i <= b ; ++ i)
#define per(i,a,b) for (int i = a ; i >= b ; -- i)
#define pii pair < int , int >
#define X first
#define Y second
#define rint read<int>
#define int long long
#define pb push_back
#define mid ( ( l + r ) >> 1 )
#define ls ( rt << 1 )
#define rs ( rt << 1 | 1 )

using std::set ;
using std::pair ;
using std::max ;
using std::min ;
using std::priority_queue ;
using std::vector ;

template < class T >
inline T read () {
T x = 0 , f = 1 ; char ch = getchar () ;
while ( ch < '0' || ch > '9' ) {
if ( ch == '-' ) f = - 1 ;
ch = getchar () ;
}
while ( ch >= '0' && ch <= '9' ) {
x = ( x << 3 ) + ( x << 1 ) + ( ch - 48 ) ;
ch = getchar () ;
}
return f * x ;
}

const int N = 1e6 + 100 ;

struct pairs { int x , y ; } ans[N] ;

int n , m , v[N] , cnt ;

inline bool cmp (pairs a , pairs b) {
if ( a.x != b.x ) return a.x < b.x ;
return a.y < b.y ;
}

signed main (int argc , char * argv[] ) {
freopen ("interval.in" , "r" , stdin) ;
freopen ("interval.out" , "w" , stdout) ;
n = rint () ; m = rint () ;
while ( m -- ) {
int x = rint () , y = rint () ;
++ v[x] ; -- v[y+1] ;
}
rep ( i , 1 , n ) v[i] += v[i-1] ;
rep ( i , 1 , n ) {
if ( v[i] == 0 ) {
ans[++cnt].x = i ;
while ( v[i] == 0 && i <= n ) ++ i ;
ans[cnt].y = i - 1 ;
}
}
std::sort ( ans + 1 , ans + cnt + 1 , cmp ) ;
rep ( i , 1 , cnt ) printf ("%lld %lld\n" , ans[i].x , ans[i].y ) ;
return 0 ;
}