敢览求 题解
闲扯 前言
本来想直接放到一起的结果发现太长了不方便阅读就单独开一个文章算逑。
由于讲题的人(指 @Caiest_Oier)自己没有写代码有些实现细节他没搞清楚,讲得有点复杂,导致被坑了。我附的代码里的注释的内容就是具体怎么被坑的,大家看个乐子就行了o(╥﹏╥)o。
正文
首先看到这种题肯定考虑树形 DP,由于操作二的存在只用子树内的信息是无法表示一个状态的,故 DP 状态的定义要结合子树外的信息。
容易想到设 $dp_{i,j}$ 表示 $i$ 的祖先的操作二增量总和在模 $K$ 意义下为 $j$,$i$ 的子树内还需要至少多少次操作。
注:本文除 DP 转移中的加法外其余加法计算均在模 $K$ 意义下进行。
首先不考虑对 $i$ 进行操作二,易得转移方程:
$$dp_{i,j}=dp_{ls(i),j}+dp_{rs(i),j}+w(i,j)$$
其中 $ls(i),rs(i)$ 分别表示结点 $i$ 的左右子树,下同。
这时候眼尖的读者(这不是一眼就看出来吗)就会发现我们在转移方程的后面加了一个 $w(i,j)$,这表示结点 $i$ 在加了 $j$ 后是否还需要进行一次操作 $1$ 使其合法。
然后再考虑操作二,容易发现一次操作二可以使 $dp_{i,j}$ 变成 $dp_{i,k}+1$,易得转移方程。
$$ dp_{i,j}=\begin{cases} \min\limits_{k=0}^{K-1}{dp_{i,k}}+1,&dp_{i,j}\ne \min\limits_{k=0}^{K-1}{dp_{i,k}}\\ dp_{i,j} &dp_{i,j}=\min\limits_{k=0}^{K-1}{dp_{i,k}} \end{cases} $$
然后你直接 DP 就能获得 $30pts$ 的高分(本题赛时最高分 $5pts$,你推出这个 DP 式子就可以薄纱全场 $11$ 人),复杂度 $O(nK)$。
考虑如何优化,容易发现对于同一个 $i$,$dp_{i,j}$ 只有两种取值,一种是 $\min_{k=0}^{K-1}{dp_{i,k}}$,另一种是 $\min_{k=0}^{K-1}{dp_{i,k}}+1$,那么我们可以对每个结点只存一个最小值,然后用某种东西存下能取到最小值的区间,设这个最小值为 $f_i$,考虑如何转移。
另外容易发现,对于同一个 $i$,$w(i,j)$ 能取到最小值的区间只可能有一个或者两个,这个性质后面有用。
设 $f_{ls(i)},f_{rs(i)},f_{i}$ 能取到最小值的区间分别是 $S(l),S(r),S(i)$,又设 $w(i,j)=0$ 的区间为 $W$,易得转移方程:
$$ \begin{cases} f_{i}=f_{ls(i)}+f_{rs(i)}, &S(i)=W\cap S(l)\cap S(r); &W\cap S(l)\cap S(r) \ne \varnothing\\ f_{i}=f_{ls(i)}+f_{rs(i)}+2, &S(i)=W\cup S(l) \cup S(r); &W \cap S(l)=\varnothing,W\cap S(r)=\varnothing,S(l)\cap S(r)=\varnothing\\ f_{i}=f_{ls(i)}+f_{rs(i)}+1, &S(i)=(W \cap S(l))\cup(W\cap S(r))\cup (S(l)\cap S(r)), & else \end{cases} $$
自己想办法看,太长了我也没办法,你可以试试 ctrl+A。
很好理解,最小值肯定是三个集合尽量多取最小值的位置,然后自己画图推一推就行了。
假如你用 bitset
实现的话,复杂度是 $O(\frac{nK}{w})$,可以得 $50pts$。
接下来隆重介绍正解:set
存二元组模拟区间的交和并。
然后这十五个字花了我 6.5kb 的代码来实现。
首先暴力合并是 $O(n^2)$ 的,但合并集合我们还有一种优化的方法,启发式合并,但是这要求我们单次合并的复杂度是 $O(\min(|S_1|,|S_2|))$,由于求交需要遍历两个集合这显然是做不到的,但是由于最初所有集合内最多有总共 $2n$ 个二元组,而一个二元组被删掉了就再也不会回来了,对删除进行势能分析,复杂度是 $O(n)$,所以我们只需要考虑修改的复杂度,故可以做到 $O(\min(|S_1|,|S_2|))$。
关于如何实现,我们分别讲,以下默认 $|S(l)|\le|S(r)|$。
$S(i)=W\cap S(l)\cap S(r)$
首先容易发现 $W$ 中的元素非常少,所以我们可以在遍历 $S(l)$ 的时候直接和 $W$ 取交,代码片段如下(变量名和叙述不统一但是懒得改了):
code
bool _ad0(set<pii> &a,set<pii> &b,set<pii> &c){// (1)!
set<pii>::iterator it=a.begin();
for(set<pii>::iterator ii=b.begin();ii!=b.end();){
pii i=*ii;
if(it==a.end()){break;}
if(i.se<it->fi){++ii;continue;}
if(i.fi>it->se){++it;continue;}
int nl=max(i.fi,it->fi),nr=min(i.se,it->se);
set<pii>::iterator jt=c.upper_bound(mkp(nl,inf));
if(jt!=c.end()){
if(jt->fi<=nr){
return true;
}
}
if(jt!=c.begin()){
if(prev(jt)->se>=nl){
return true;
}
}
if(i.se>it->se){
++it;
}else{
++ii;
}
}
return false;
}
- 这个函数是用来判断三个集合有没有交的。
然后考虑如何实现合并操作,思路很简单,首先像上面这个函数一样算出 nl,nr
,然后在 $S(r)$ 中从这两个位置切开,把没有被 $S(l)$ 中的区间完全覆盖的全部删掉。
code
void split(int k,set<pii> &a){// (1)!
set<pii>::iterator it=a.upper_bound(mkp(k,inf));
if(it==a.begin()) return;
--it;
if(it->fi>k||it->se<k) return;
pii ii=*it;
a.erase(it);
if(ii.fi<=k-1) a.insert(mkp(ii.fi,k-1));
if(k<=ii.se) a.insert(mkp(k,ii.se));
}
void intersect3(set<pii> &a,set<pii> &b,set<pii> &c){
set<pii>::iterator it=a.begin(),pt;
int nw=-1;
for(set<pii>::iterator ii=b.begin();ii!=b.end();){
pii i=*ii;
if(it==a.end()){break;}
if(i.se<it->fi){++ii;continue;}
if(i.fi>it->se){++it;continue;}
int nl=max(i.fi,it->fi),nr=min(i.se,it->se);
set<pii>::iterator jt,kt;
jt=c.upper_bound(mkp(nl,inf));
if(jt!=c.begin()){
if(prev(jt)->fi<nl&&prev(jt)->se>=nl){
split(nl,c);
}
}
kt=c.upper_bound(mkp(nr,inf));
if(kt!=c.begin()){
if(prev(kt)->se>nr){
split(nr+1,c);
}
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end()&&qt->se<nl;){
qt++;
c.erase(prev(qt));
}
nw=nr;
if(i.se>it->se){
++it;
}else{
++ii;
}
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end();){
qt++;
c.erase(prev(qt));
}
}
- 这个
split
后面还会用到。
$S(i)=W\cup S(l)\cup S(r)$
这个非常简单,因为你发现要求并时所有区间必定是没有交的。
code
bool _ad2(set<pii> &a,set<pii> &b,set<pii> &c){
for(auto i:a){
set<pii>::iterator it=b.lower_bound(mkp(i.fi,0));
if(it!=b.end()&&it->fi<=i.se) return false;
if(it!=b.begin()&&prev(it)->se>=i.fi) return false;
it=c.lower_bound(mkp(i.fi,0));
if(it!=c.end()&&it->fi<=i.se) return false;
if(it!=c.begin()&&prev(it)->se>=i.fi) return false;
}
for(auto i:b){// (1)!
set<pii>::iterator it=c.lower_bound(mkp(i.fi,0));
if(it!=c.end()&&it->fi<=i.se) return false;
if(it!=c.begin()&&prev(it)->se>=i.fi) return false;
}
return true;
}
void union2(set<pii> &a,set<pii> &c){
for(auto i:a){
c.insert(i);
}
}
- 这个复杂度为什么对呢?容易发现 $|W|$ 只可能等于 $1$ 或 $2$,几乎可以看做常数。
$S(i)=(W \cap S(l))\cup(W\cap S(r))\cup (S(l)\cap S(r))$
这个直接算不能做到 $O(\min(|S(l)|,|S(r)|))$,考虑化一下式子。
因为 交对并有分配率,所以原式 $=[W\cap (S(l)\cup S(r)]\cup(S(l)\cap S(r))$。
这就非常好做了,在 $W$ 内的 $S(l),S(r)$ 并起来,其余的交起来,注意到这里的并也保证两两不交,不然它就是前面第一种情况了。
code
void union3(set<pii> &a,set<pii> &b,set<pii> &c){
//(a&b)|(b&c)|(a&c) = (b&c)|(a&(b|c))
for(auto i:a){
split(i.fi,b);split(i.se+1,b);
split(i.fi,c);split(i.se+1,c);
}
set<pii>::iterator it=a.begin(),pt=c.begin(),at=a.begin();
int nw=-1;
for(auto i:b){
if(it->se<i.fi&&it!=prev(a.end())) ++it;
int qwer,nnw;
if(i.fi>=it->fi&&i.se<=it->se){
set<pii>::iterator jt,kt,st;
c.insert(i);
qwer=i.fi;nnw=i.se;
}else{
int nl=i.fi,nr=i.se;
set<pii>::iterator jt,kt;
jt=c.upper_bound(mkp(nl,inf));
if(jt!=c.begin()){
if(prev(jt)->fi<nl&&prev(jt)->se>=nl){
split(nl,c);
}
}
kt=c.upper_bound(mkp(nr,inf));
if(kt!=c.begin()){
if(prev(kt)->se>nr){
split(nr+1,c);
}
}
qwer=nl;nnw=nr;
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end()&&qt->se<qwer;){
if(at->se<qt->fi&&at!=prev(a.end())) ++at;
qt++;
if(prev(qt)->se<at->fi||prev(qt)->fi>at->se) c.erase(prev(qt));
}
nw=nnw;
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end();){
if(at->se<qt->fi&&at!=prev(a.end())) ++at;
qt++;
if(prev(qt)->se<at->fi||prev(qt)->fi>at->se) c.erase(prev(qt));
}
}
然后就做完了。
code
完整代码
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define forup(i,s,e) for(int i=(s);i<=(e);i++)
#define fordown(i,s,e) for(int i=(s);i>=(e);i--)
//#define DEBUG
using namespace std;
using pii=pair<int,int>;
#define fi first
#define se second
#define mkp make_pair
#define gc getchar()
inline int read(){
int x=0,f=1;char c;
while(!isdigit(c=gc)) if(c=='-') f=-1;
while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=gc;}
return x*f;
}
#undef gc
const int N=2e5+5,inf=0x3f3f3f3f;
int n,a[N],b[N],son[N][2],m;
int dp[N];
set<pii> w[N];
int rt[N];
void split(int k,set<pii> &a){
set<pii>::iterator it=a.upper_bound(mkp(k,inf));
if(it==a.begin()) return;
--it;
if(it->fi>k||it->se<k) return;
pii ii=*it;
a.erase(it);
if(ii.fi<=k-1) a.insert(mkp(ii.fi,k-1));
if(k<=ii.se) a.insert(mkp(k,ii.se));
}
bool _ad0(set<pii> &a,set<pii> &b,set<pii> &c){
set<pii>::iterator it=a.begin();
for(set<pii>::iterator ii=b.begin();ii!=b.end();){
pii i=*ii;
if(it==a.end()){break;}
if(i.se<it->fi){++ii;continue;}
if(i.fi>it->se){++it;continue;}
int nl=max(i.fi,it->fi),nr=min(i.se,it->se);
set<pii>::iterator jt=c.upper_bound(mkp(nl,inf));
if(jt!=c.end()){
if(jt->fi<=nr){
return true;
}
}
if(jt!=c.begin()){
if(prev(jt)->se>=nl){
return true;
}
}
if(i.se>it->se){
++it;
}else{
++ii;
}
}
return false;
}
void intersect3(set<pii> &a,set<pii> &b,set<pii> &c){
set<pii>::iterator it=a.begin(),pt;
int nw=-1;
for(set<pii>::iterator ii=b.begin();ii!=b.end();){
pii i=*ii;
if(it==a.end()){break;}
if(i.se<it->fi){++ii;continue;}
if(i.fi>it->se){++it;continue;}
int nl=max(i.fi,it->fi),nr=min(i.se,it->se);
set<pii>::iterator jt,kt;
jt=c.upper_bound(mkp(nl,inf));
if(jt!=c.begin()){
if(prev(jt)->fi<nl&&prev(jt)->se>=nl){
// int jr=prev(jt)->se;
// int jl=prev(jt)->fi;
// c.erase(prev(jt));
split(nl,c);
// c.erase(c.lower_bound(mkp(jl,0)));
}
}
kt=c.upper_bound(mkp(nr,inf));
if(kt!=c.begin()){
if(prev(kt)->se>nr){
// int kl=prev(kt)->fi;
// c.erase(prev(kt));
split(nr+1,c);
// c.erase(c.lower_bound(mkp(nr+1,0)));
}
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end()&&qt->se<nl;){
qt++;
c.erase(prev(qt));
}
nw=nr;
if(i.se>it->se){
++it;
}else{
++ii;
}
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end();){
qt++;
c.erase(prev(qt));
}
}
bool _ad2(set<pii> &a,set<pii> &b,set<pii> &c){
for(auto i:a){
set<pii>::iterator it=b.lower_bound(mkp(i.fi,0));
if(it!=b.end()&&it->fi<=i.se) return false;
if(it!=b.begin()&&prev(it)->se>=i.fi) return false;
it=c.lower_bound(mkp(i.fi,0));
if(it!=c.end()&&it->fi<=i.se) return false;
if(it!=c.begin()&&prev(it)->se>=i.fi) return false;
}
for(auto i:b){
set<pii>::iterator it=c.lower_bound(mkp(i.fi,0));
if(it!=c.end()&&it->fi<=i.se) return false;
if(it!=c.begin()&&prev(it)->se>=i.fi) return false;
}
return true;
}
void union2(set<pii> &a,set<pii> &c){
for(auto i:a){
c.insert(i);
// set<pii>::iterator jt,kt,st;
// int nl=i.fi,nr=i.se;
// jt=c.upper_bound(mkp(i.fi,inf));
// if(jt!=c.begin()){
// if(prev(jt)->se>=i.fi){
// nl=min(nl,prev(jt)->fi);
// st=prev(jt);
// }
// }
// kt=c.upper_bound(mkp(i.se,inf));
// if(kt!=c.begin()){
// if(prev(kt)->fi<=i.se){
// nr=max(nr,prev(kt)->se);
// }
// }
// st=c.lower_bound(mkp(nl,0));
// for(set<pii>::iterator lt=st;lt!=c.end()&<->se<=nr;){
// ++lt;
// c.erase(prev(lt));
// }
// c.insert(mkp(nl,nr));
}
}
void union3(set<pii> &a,set<pii> &b,set<pii> &c){
//(a&b)|(b&c)|(a&c) = (b&c)|(a&(b|c))
for(auto i:a){
split(i.fi,b);split(i.se+1,b);
split(i.fi,c);split(i.se+1,c);
}
set<pii>::iterator it=a.begin(),pt=c.begin(),at=a.begin();
int nw=-1;
for(auto i:b){
if(it->se<i.fi&&it!=prev(a.end())) ++it;
int qwer,nnw;
if(i.fi>=it->fi&&i.se<=it->se){
set<pii>::iterator jt,kt,st;
// int nl=i.fi,nr=i.se;
// jt=c.upper_bound(mkp(i.fi,inf));
// if(jt!=c.begin()){
// if(prev(jt)->se>=i.fi){
// nl=min(nl,prev(jt)->fi);
// }
// }
// kt=c.upper_bound(mkp(i.se,inf));
// if(kt!=c.begin()){
// if(prev(kt)->fi<=i.se){
// nr=max(nr,prev(kt)->se);
// }
// }
// st=c.lower_bound(mkp(nl,0));
// for(set<pii>::iterator lt=st;lt!=c.end()&<->se<=nr;){
// ++lt;
// c.erase(prev(lt));
// }
// c.insert(mkp(nl,nr));
c.insert(i);
qwer=i.fi;nnw=i.se;
}else{
int nl=i.fi,nr=i.se;
set<pii>::iterator jt,kt;
// jt=c.upper_bound(mkp(nl,inf));
// if(jt!=c.begin()){
// if(prev(jt)->fi<=nl&&prev(jt)->se>=nl){
// int jr=min(nr,prev(jt)->se);
// c.erase(prev(jt));
// c.insert(mkp(nl,jr)).fi;
// }
// }
// kt=c.upper_bound(mkp(nr,inf));
// if(kt!=c.begin()){
// if(prev(kt)->fi<=nr&&prev(kt)->se>=nr){
// int kl=max(prev(kt)->fi,nl);
// c.erase(prev(kt));
// c.insert(mkp(kl,nr)).fi;
// }
// }
jt=c.upper_bound(mkp(nl,inf));
if(jt!=c.begin()){
if(prev(jt)->fi<nl&&prev(jt)->se>=nl){
// int jr=prev(jt)->se;
// int jl=prev(jt)->fi;
// c.erase(prev(jt));
split(nl,c);
// c.erase(c.lower_bound(mkp(jl,0)));
}
}
kt=c.upper_bound(mkp(nr,inf));
if(kt!=c.begin()){
if(prev(kt)->se>nr){
// int kl=prev(kt)->fi;
// c.erase(prev(kt));
split(nr+1,c);
// c.erase(c.lower_bound(mkp(nr+1,0)));
}
}
qwer=nl;nnw=nr;
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end()&&qt->se<qwer;){
if(at->se<qt->fi&&at!=prev(a.end())) ++at;
qt++;
if(prev(qt)->se<at->fi||prev(qt)->fi>at->se) c.erase(prev(qt));
}
nw=nnw;
}
pt=c.upper_bound(mkp(nw,inf));
for(set<pii>::iterator qt=pt;qt!=c.end();){
if(at->se<qt->fi&&at!=prev(a.end())) ++at;
qt++;
if(prev(qt)->se<at->fi||prev(qt)->fi>at->se) c.erase(prev(qt));
}
}
void dfs(int x){
if(x==0) return;
if(son[x][0]) dfs(son[x][0]);
if(son[x][1]) dfs(son[x][1]);
if(son[x][0]==0&&son[x][1]==0) return;
if(son[x][1]==0||son[x][0]==0){
w[rt[0]].clear();
w[rt[0]].insert(mkp(0,m-1));
}
int l=son[x][0],r=son[x][1];
dp[x]=dp[l]+dp[r];
#ifdef DEBUG
printf("======%d|%d|%d\n",x,l,r);
printf("%d||",x);
for(auto i:w[rt[x]]) printf("%d %d|",i.fi,i.se);
printf("\n%d||",l);
for(auto i:w[rt[l]]) printf("%d %d|",i.fi,i.se);
printf("\n%d||",r);
for(auto i:w[rt[r]]) printf("%d %d|",i.fi,i.se);
puts("");
#endif
if(w[rt[l]].size()>w[rt[r]].size()){
swap(rt[l],rt[r]);
}
// if(w[rt[x]].size()>w[rt[l]].size()){
// swap(rt[x],rt[l]);
// }
if(_ad0(w[rt[x]],w[rt[l]],w[rt[r]])){
intersect3(w[rt[x]],w[rt[l]],w[rt[r]]);
#ifdef DEBUG
puts("0");
#endif
}else if(_ad2(w[rt[x]],w[rt[l]],w[rt[r]])){
dp[x]+=2;
union2(w[rt[x]],w[rt[r]]);
union2(w[rt[l]],w[rt[r]]);
#ifdef DEBUG
puts("2");
#endif
}else{
dp[x]+=1;
union3(w[rt[x]],w[rt[l]],w[rt[r]]);
#ifdef DEBUG
puts("1");
#endif
}
swap(rt[x],rt[r]);
#ifdef DEBUG
for(auto i:w[rt[x]]){
printf(" %d %d|\n",i.fi,i.se);
}
#endif
}
signed main(){
n=read();m=read();
forup(i,1,n){
a[i]=read();b[i]=read();son[i][0]=read();son[i][1]=read();
rt[i]=i;
}
forup(i,1,n){
if(a[i]>b[i]){
w[rt[i]].insert(mkp(0,m-a[i]-1));
if(b[i]!=0) w[rt[i]].insert(mkp(m-b[i],m-1));
}else{
w[rt[i]].insert(mkp(m-b[i],m-a[i]-1));
}
#ifdef DEBUG
printf("%d||",i);
for(auto j:w[rt[i]]){
printf("%d %d|",j.fi,j.se);
}
puts("");
#endif
}
dfs(1);
int ans=dp[1];
if(w[rt[1]].begin()->fi>0) ans++;
printf("%d\n",ans);
}
另外贴一下赛时最高分代码来自 @元神大王乔安娜。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
code
// author:LGM_Joanna_
#include <bits/stdc++.h>
#define marry return
#define int long long
#define lowbit(x) (x&-x)
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<48||ch>57)f=ch=='-'?-1:1,ch=getchar();
while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=getchar();
return x*f;}
using namespace std;
const int inf=1e18;
const int F=0;
const int mod=114514;
signed main()
{
puts("2");
/*
摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆
摆摆 摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆 摆摆 摆摆摆摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆
摆摆摆摆 摆 摆摆摆摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆 摆摆摆 摆摆摆摆摆摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆摆摆摆
摆 摆摆摆摆摆 摆摆摆摆摆摆摆摆 摆摆 摆摆 摆摆 摆摆摆摆摆摆摆摆
摆摆摆摆 摆 摆摆摆摆摆摆摆摆 摆摆 摆摆摆摆摆摆摆摆摆
摆摆摆摆 摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆 摆摆摆 摆摆摆摆摆摆摆
摆摆摆摆 摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆
摆摆摆摆 摆 摆摆摆 摆摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆 摆摆摆摆摆摆
摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆摆摆摆 摆摆 摆摆摆摆 摆摆摆摆摆摆摆
摆摆摆摆 摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆摆摆 摆 摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆 摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆 摆摆 摆摆摆摆摆
摆摆摆 摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆 摆摆 摆 摆摆 摆 摆摆摆摆摆
摆摆摆 摆摆摆摆 摆摆 摆 摆摆摆摆摆 摆 摆 摆摆 摆 摆摆摆摆摆
摆摆摆 摆摆 摆 摆摆摆摆摆摆摆 摆摆 摆摆摆摆摆
摆摆摆摆摆 摆摆摆摆摆 摆 摆摆摆摆摆摆摆 摆摆摆摆摆 摆摆摆摆摆摆摆摆摆
摆摆摆摆摆 摆摆摆摆摆 摆 摆摆摆摆摆摆摆 摆摆摆 摆摆摆摆摆摆
摆摆 摆摆 摆 摆摆摆摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆摆摆
摆摆摆摆 摆摆摆 摆摆 摆 摆摆摆摆摆 摆摆摆摆摆 摆摆摆摆摆摆摆摆摆
摆摆摆摆 摆摆摆 摆摆 摆 摆摆摆摆摆 摆 摆摆 摆摆摆摆摆
摆摆摆摆 摆摆摆 摆摆 摆 摆摆摆摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆摆摆摆
摆摆摆 摆摆 摆 摆摆摆摆 摆摆摆摆摆 摆 摆摆摆摆 摆摆摆 摆摆摆摆摆摆
摆摆摆 摆摆摆 摆摆摆 摆摆摆摆摆摆 摆摆摆 摆摆摆摆摆 摆摆摆摆摆
摆摆 摆摆摆摆摆 摆摆摆摆 摆摆摆摆摆摆摆 摆摆 摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆
摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆摆
*/
marry F;
}