DLUT onsite【线段树+数学+dp专场有木有!!!】[改](D + F)(zju 3542 + zju 3544)
虽然是用了10小时来打5小时的比赛,但也弱爆了。神马都不会啊。A zoj 3539
搜索+字符串,连暴力都不会写
B zoj 3540
竟然是矩形并!!!。。不过就算是“矩形并”,也不会写。。线段树神马的,都不会哇。。
C zoj 3541
好巧妙好经典的N^2DP,我不会啊。
D zoj 3542
纯模拟。。。善用cctype和%x
代码:
#include
<
iostream
>
#include < cstdio >
#include < cstring >
#include < string >
#include < cstdlib >
#include < cctype >
#include < map >
#include < set >
#include < bitset >
#include < vector >
#include < algorithm >
#include < cmath >
#define PB push_back
using namespace std;
const int inf = ~ 0u >> 1 ;
const double eps = 1e - 8 ;
const double pi = acos( - 1.0 );
int sgn( double x)
{
return fabs(x) < eps ? 0 :x < - eps ?- 1 : 1 ;
}
char str[ 5000 ];
int main()
{
while (cin.getline(str, 5000 ))
{
int l = strlen(str);
int i = 0 ;
char opt[ 20 ];
int cnt = 0 ;
while ( 1 )
{
char row[ 5 ];
sprintf(row, " %x " ,i);
for ( int j = 0 ;j < 4 - strlen(row);j ++ )
putchar( ' 0 ' );
printf( " %s: " ,row);
bool mark = true ;
for ( int j = 0 ;j < 16 ;j ++ )
{
opt[j] = mark ? str[i]: - 1 ;
i ++ ;
if (i == l)
mark = false ;
}
for ( int j = 0 ;j < 16 ;j ++ )
{
if (opt[j] != - 1 )
printf( " %x " ,opt[j]);
else
printf( " " );
if (j % 2 )
printf( " " );
}
for ( int j = 0 ;j < 16 ;j ++ )
{
if (opt[j] == - 1 )
break ;
if (islower(opt[j]))
opt[j] = toupper(opt[j]);
else if (isupper(opt[j]))
opt[j] = tolower(opt[j]);
printf( " %c " ,opt[j]);
}
puts( "" );
if ( ! mark)
break ;
}
}
}
#include < cstdio >
#include < cstring >
#include < string >
#include < cstdlib >
#include < cctype >
#include < map >
#include < set >
#include < bitset >
#include < vector >
#include < algorithm >
#include < cmath >
#define PB push_back
using namespace std;
const int inf = ~ 0u >> 1 ;
const double eps = 1e - 8 ;
const double pi = acos( - 1.0 );
int sgn( double x)
{
return fabs(x) < eps ? 0 :x < - eps ?- 1 : 1 ;
}
char str[ 5000 ];
int main()
{
while (cin.getline(str, 5000 ))
{
int l = strlen(str);
int i = 0 ;
char opt[ 20 ];
int cnt = 0 ;
while ( 1 )
{
char row[ 5 ];
sprintf(row, " %x " ,i);
for ( int j = 0 ;j < 4 - strlen(row);j ++ )
putchar( ' 0 ' );
printf( " %s: " ,row);
bool mark = true ;
for ( int j = 0 ;j < 16 ;j ++ )
{
opt[j] = mark ? str[i]: - 1 ;
i ++ ;
if (i == l)
mark = false ;
}
for ( int j = 0 ;j < 16 ;j ++ )
{
if (opt[j] != - 1 )
printf( " %x " ,opt[j]);
else
printf( " " );
if (j % 2 )
printf( " " );
}
for ( int j = 0 ;j < 16 ;j ++ )
{
if (opt[j] == - 1 )
break ;
if (islower(opt[j]))
opt[j] = toupper(opt[j]);
else if (isupper(opt[j]))
opt[j] = tolower(opt[j]);
printf( " %c " ,opt[j]);
}
puts( "" );
if ( ! mark)
break ;
}
}
}
Up
backward paragraph
E zoj 3543
N^2 dp,claire大神想了个神做法N^3,结果TLE了,哈哈~
F zoj 3544
shi哥的路径压缩的方法场上想到了,不会敲;到现在也不会敲。拿stl企图骗过去,果断TLE。好紧啊。
题解:
正着做就是裸体有lazy tag的线段树,竟然在zoj上可以过,太orz了。
刷板报什么的,有这样一个性质,后面的涂色不会被前面的覆盖,果断倒着做。
倒着做也可以某种线段树,不需要重复覆盖的,应该会比正着做要快。
(ps,既然正着做倒着做在zoj上都能过,为啥10.2的时候就只有那么点人过了F?不解)
说一下正解吧,太orz shi哥了。
既然是不会重复覆盖,那么只要把已经覆盖过的删除了就好了,再覆盖的时候对删除的跳过去就行。这样最多删除O(m*n)次。
但是怎样快速查找呢?就是并查集的做法了,并查集路径压缩之后的复杂度在整数范围内最大为O(5)。
本题中的并查集:
删除[l,r]区间:
1.假如起始点未被删除过,那么就从这个点开始逐次删除,并统计删除的点数,返回删除的点数即可。
删除的过程中,记得将刚刚被删除的点的skip域指向本次删除区间的左端点。
2.假如起始点已经被删除过,那么就找这个点的skip域,直到找到一个可删除节点或者到本段的段尾为止(m)。
而接下来逐次删除的时候,删完的点的skip应该指向这个新的节点。
记得查找的时候,附带路径压缩,并查集的路径压缩各位大神肯定都会写吧?
删完了一个区间之后,把区间开始删除的点的skip域指向最后的点(不在本次删除范围内的可删除节点或者段末)。
牢记:路径压缩的时候是把所有儿子都指向父亲。
最后更新“最后节点“的时候,是将删除区间的起始点指向最后节点(根)。
以上说得很乱,画图解释就是:
这是naive的并查集,a exists in (l,r],a -> l,l -> (r+1)。
路径压缩的时候,l1 -> l2 -> l3 -> r => l1 -> r ,l2 -> r , l3 -> r。
关键代码在51~69行。(因为带了行号,所以复制不方便了哈。。)
数据结构神马的太神奇了。
代码如下:
1
#include
<
iostream
>
2 #include < cstdio >
3 #include < cstring >
4 #include < string >
5 #include < cstdlib >
6 #include < cctype >
7 #include < map >
8 #include < set >
9 #include < bitset >
10 #include < vector >
11 #include < algorithm >
12 #include < cmath >
13 #define PB push_back
14 #define sqr(x) ((x) * (x))
15 using namespace std;
16 const int inf = ~ 0u >> 1 ;
17 const double eps = 1e - 8 ;
18 const double pi = acos( - 1.0 );
19 int sgn( double x)
20 {
21 return fabs(x) < eps ? 0 :x < - eps ?- 1 : 1 ;
22 }
23 #define maxn 205
24 #define maxm 50005
25 int n,m,q;
26 inline int ab( int x)
27 {
28 return x >= 0 ? x: - x;
29 }
30 struct method
31 {
32 int type;
33 int cnt;
34 int in [ 7 ];
35 }mth[maxm];
36 int ans[ 10 ];
37 struct skiplist
38 {
39 int skip[maxm];
40 bool tr[maxm];
41 void init( int m)
42 {
43 fill(tr,tr + m, 1 );
44 }
45 int jump( int pos)
46 {
47 if (pos >= m)
48 return m;
49 return tr[pos] ? pos:skip[pos] = jump(skip[pos]);
50 }
51 int erase( int l, int r)
52 {
53 int now = jump(l),pos = now; //
54 int num = 0 ;
55 while (pos <= r)
56 {
57 if (tr[pos])
58 {
59 tr[pos] = false ;
60 skip[pos] = now;
61 pos ++ ;
62 num ++ ;
63 }
64 else
65 pos = jump(pos);
66 }
67 skip[now] = pos;
68 return num;
69 }
70 }skip[maxn];
71 void gao( int row, int le, int ri, int co)
72 {
73 ans[co] += skip[row].erase(le,ri);
74 }
75 int main()
76 {
77 while (scanf( " %d %d %d " , & n, & m, & q) == 3 )
78 {
79 for ( int i = 0 ;i < n;i ++ )
80 skip[i].init(m);
81 memset(ans, 0 , sizeof (ans));
82 for ( int i = 0 ;i < q;i ++ )
83 {
84 char opt[ 20 ];
85 int a[ 10 ];
86 scanf( " %s " ,opt);
87 switch (opt[ 0 ])
88 {
89 case ' C ' :
90 mth[i].type = 1 ;
91 mth[i].cnt = 4 ;
92 break ;
93 case ' D ' :
94 mth[i].type = 2 ;
95 mth[i].cnt = 4 ;
96 break ;
97 case ' R ' :
98 mth[i].type = 3 ;
99 mth[i].cnt = 5 ;
100 break ;
101 case ' T ' :
102 mth[i].type = 4 ;
103 mth[i].cnt = 4 ;
104 break ;
105 }
106 for ( int j = 0 ;j < mth[i].cnt;j ++ )
107 scanf( " %d " , & mth[i]. in [j]);
108 }
109 for ( int i = q - 1 ;i >= 0 ;i -- )
110 {
111 int hi,lo,le,ri,c,cnt = mth[i].cnt,type = mth[i].type;
112 int in [ 10 ];
113 for ( int j = 0 ;j < cnt;j ++ )
114 in [j] = mth[i]. in [j];
115 c = in [cnt - 1 ];
116 if (mth[i].type == 1 )
117 {
118 hi = max( 0 , in [ 0 ] - in [ 2 ]);
119 lo = min(n - 1 , in [ 0 ] + in [ 2 ]);
120 for ( int j = hi;j <= lo;j ++ )
121 {
122 int offset = floor(sqrt(sqr( in [ 2 ]) - sqr(j - in [ 0 ])));
123 le = max( 0 , in [ 1 ] - offset);
124 ri = min(m - 1 , in [ 1 ] + offset);
125 gao(j,le,ri,c);
126 }
127 }
128 else if (mth[i].type == 2 )
129 {
130 hi = max( 0 , in [ 0 ] - in [ 2 ]);
131 lo = min(n - 1 , in [ 0 ] + in [ 2 ]);
132 for ( int j = hi;j <= lo;j ++ )
133 {
134 int offset = in [ 2 ] - ab(j - in [ 0 ]);
135 le = max( 0 , in [ 1 ] - offset);
136 ri = min(m - 1 , in [ 1 ] + offset);
137 gao(j,le,ri,c);
138 }
139 }
140 else if (mth[i].type == 3 )
141 {
142 hi = in [ 0 ];
143 lo = min(n - 1 , in [ 0 ] + in [ 2 ] - 1 );
144 for ( int j = hi;j <= lo;j ++ )
145 {
146 le = in [ 1 ];
147 ri = min(m - 1 , in [ 1 ] + in [ 3 ] - 1 );
148 gao(j,le,ri,c);
149 }
150 }
151 else
152 {
153 hi = in [ 0 ];
154 lo = min(n - 1 , in [ 0 ] + in [ 2 ] / 2 );
155 for ( int j = hi;j <= lo;j ++ )
156 {
157 int offset = ( in [ 2 ] - (j - in [ 0 ]) * 2 ) / 2 ;
158 le = max( 0 , in [ 1 ] - offset);
159 ri = min(m - 1 , in [ 1 ] + offset);
160 gao(j,le,ri,c);
161 }
162 }
163 }
164 for ( int i = 1 ;i <= 9 ;i ++ )
165 printf( " %d%c " ,ans[i],i == 9 ? ' \n ' : ' ' );
166 }
167 }
168
2 #include < cstdio >
3 #include < cstring >
4 #include < string >
5 #include < cstdlib >
6 #include < cctype >
7 #include < map >
8 #include < set >
9 #include < bitset >
10 #include < vector >
11 #include < algorithm >
12 #include < cmath >
13 #define PB push_back
14 #define sqr(x) ((x) * (x))
15 using namespace std;
16 const int inf = ~ 0u >> 1 ;
17 const double eps = 1e - 8 ;
18 const double pi = acos( - 1.0 );
19 int sgn( double x)
20 {
21 return fabs(x) < eps ? 0 :x < - eps ?- 1 : 1 ;
22 }
23 #define maxn 205
24 #define maxm 50005
25 int n,m,q;
26 inline int ab( int x)
27 {
28 return x >= 0 ? x: - x;
29 }
30 struct method
31 {
32 int type;
33 int cnt;
34 int in [ 7 ];
35 }mth[maxm];
36 int ans[ 10 ];
37 struct skiplist
38 {
39 int skip[maxm];
40 bool tr[maxm];
41 void init( int m)
42 {
43 fill(tr,tr + m, 1 );
44 }
45 int jump( int pos)
46 {
47 if (pos >= m)
48 return m;
49 return tr[pos] ? pos:skip[pos] = jump(skip[pos]);
50 }
51 int erase( int l, int r)
52 {
53 int now = jump(l),pos = now; //
54 int num = 0 ;
55 while (pos <= r)
56 {
57 if (tr[pos])
58 {
59 tr[pos] = false ;
60 skip[pos] = now;
61 pos ++ ;
62 num ++ ;
63 }
64 else
65 pos = jump(pos);
66 }
67 skip[now] = pos;
68 return num;
69 }
70 }skip[maxn];
71 void gao( int row, int le, int ri, int co)
72 {
73 ans[co] += skip[row].erase(le,ri);
74 }
75 int main()
76 {
77 while (scanf( " %d %d %d " , & n, & m, & q) == 3 )
78 {
79 for ( int i = 0 ;i < n;i ++ )
80 skip[i].init(m);
81 memset(ans, 0 , sizeof (ans));
82 for ( int i = 0 ;i < q;i ++ )
83 {
84 char opt[ 20 ];
85 int a[ 10 ];
86 scanf( " %s " ,opt);
87 switch (opt[ 0 ])
88 {
89 case ' C ' :
90 mth[i].type = 1 ;
91 mth[i].cnt = 4 ;
92 break ;
93 case ' D ' :
94 mth[i].type = 2 ;
95 mth[i].cnt = 4 ;
96 break ;
97 case ' R ' :
98 mth[i].type = 3 ;
99 mth[i].cnt = 5 ;
100 break ;
101 case ' T ' :
102 mth[i].type = 4 ;
103 mth[i].cnt = 4 ;
104 break ;
105 }
106 for ( int j = 0 ;j < mth[i].cnt;j ++ )
107 scanf( " %d " , & mth[i]. in [j]);
108 }
109 for ( int i = q - 1 ;i >= 0 ;i -- )
110 {
111 int hi,lo,le,ri,c,cnt = mth[i].cnt,type = mth[i].type;
112 int in [ 10 ];
113 for ( int j = 0 ;j < cnt;j ++ )
114 in [j] = mth[i]. in [j];
115 c = in [cnt - 1 ];
116 if (mth[i].type == 1 )
117 {
118 hi = max( 0 , in [ 0 ] - in [ 2 ]);
119 lo = min(n - 1 , in [ 0 ] + in [ 2 ]);
120 for ( int j = hi;j <= lo;j ++ )
121 {
122 int offset = floor(sqrt(sqr( in [ 2 ]) - sqr(j - in [ 0 ])));
123 le = max( 0 , in [ 1 ] - offset);
124 ri = min(m - 1 , in [ 1 ] + offset);
125 gao(j,le,ri,c);
126 }
127 }
128 else if (mth[i].type == 2 )
129 {
130 hi = max( 0 , in [ 0 ] - in [ 2 ]);
131 lo = min(n - 1 , in [ 0 ] + in [ 2 ]);
132 for ( int j = hi;j <= lo;j ++ )
133 {
134 int offset = in [ 2 ] - ab(j - in [ 0 ]);
135 le = max( 0 , in [ 1 ] - offset);
136 ri = min(m - 1 , in [ 1 ] + offset);
137 gao(j,le,ri,c);
138 }
139 }
140 else if (mth[i].type == 3 )
141 {
142 hi = in [ 0 ];
143 lo = min(n - 1 , in [ 0 ] + in [ 2 ] - 1 );
144 for ( int j = hi;j <= lo;j ++ )
145 {
146 le = in [ 1 ];
147 ri = min(m - 1 , in [ 1 ] + in [ 3 ] - 1 );
148 gao(j,le,ri,c);
149 }
150 }
151 else
152 {
153 hi = in [ 0 ];
154 lo = min(n - 1 , in [ 0 ] + in [ 2 ] / 2 );
155 for ( int j = hi;j <= lo;j ++ )
156 {
157 int offset = ( in [ 2 ] - (j - in [ 0 ]) * 2 ) / 2 ;
158 le = max( 0 , in [ 1 ] - offset);
159 ri = min(m - 1 , in [ 1 ] + offset);
160 gao(j,le,ri,c);
161 }
162 }
163 }
164 for ( int i = 1 ;i <= 9 ;i ++ )
165 printf( " %d%c " ,ans[i],i == 9 ? ' \n ' : ' ' );
166 }
167 }
168
G zoj 3445
状态dp+ac自动机,orz ykwd大神。
H zoj 3546
因为有凹多边形的存在,我只能想到N!的做法。这,旋转路径规划?怎么想起了昨晚的rujia几何场的最后一题,谁更难真不好说。
I zoj 3547
四次方和公式+暴力容斥,orz claire_大神
J zoj 3548
弱爆了弱爆了。