C.Nuske vs Phantom Thnook
把蓝点看成图上的点,相邻的蓝点看做图上的连边。
保证了是树,那么连通块数=点数-边数
*D.A or…or B Problem
妙。从位的组合角度完全没有思路。应该从集合角度考虑,最大化可以选择的连续区间:
A = B A=B A=B答案为1。
否则找到 A , B A,B A,B不同的最高位 k k k,再高的位 A , B A,B A,B相同,都看做0即可。
去掉比 k k k高的位后: 0 ≤ A < 2 k , 2 k ≤ B < 2 k + 1 0\leq A<2^k,2^k\leq B<2^{k+1} 0≤A<2k,2k≤B<2k+1
由
(
A
o
r
B
)
≥
A
,
(
A
o
r
B
)
≥
B
(A\ or\ B)\geq A,(A\ or \ B)\geq B
(A or B)≥A,(A or B)≥B得到:
[
A
,
2
k
)
[A,2^k)
[A,2k)子集能或出
[
A
,
2
k
)
[A,2^k)
[A,2k),设
B
B
B除
k
k
k位外的最高为1的位为
t
t
t,则
[
2
k
,
B
]
[2^k,B]
[2k,B]子集能或出
[
2
k
,
2
k
+
2
t
+
1
)
[2^k,2^k+2^{t+1})
[2k,2k+2t+1),那么
[
A
,
2
k
)
∪
[
2
k
,
B
]
[A,2^k)\cup[2^k,B]
[A,2k)∪[2k,B]子集能或出
[
2
k
+
A
,
2
k
+
1
)
[2^k+A,2^{k+1})
[2k+A,2k+1)。
三个集合合并后就是答案。
*E.Mr.Aoki Incubator
一个点可以染色的点共有四种:
- x ′ < x , v ′ > v x'< x,v'>v x′<x,v′>v
- x ′ > x , v ′ < v x'>x,v'< v x′>x,v′<v
- x ′ < x , v ′ < v 且 v ′ > 某 个 2 类 点 的 v x'< x,v'< v且v'>某个2类点的v x′<x,v′<v且v′>某个2类点的v
- x ′ > x , v ′ > v 且 v ′ < 某 个 1 类 点 的 v x'>x,v'>v且v'< 某个1类点的v x′>x,v′>v且v′<某个1类点的v
将点按速度排序,找到最小的 j j j满足 x j ≥ x i x_j\geq x_i xj≥xi,最大的 k k k满足 x k ≤ x i x_k\leq x_i xk≤xi,发现 i i i能染色的恰好就是这个连续区间 [ j , k ] [j,k] [j,k]。且任意两个点的染色区间不存在包含关系,即 l < l ′ ≤ r ′ < r l<l'\leq r'<r l<l′≤r′<r。
将每个点按 r r r第一关键字, l l l第二关键字排序, f [ i ] f[i] f[i]表示前 i i i个点被染色的方案数,前缀和优化转移即可。
*F.Kenus the Ancient Greek
结论题。
欧几里得最大步数明示套斐波那契数列。设 f ( x , y ) f(x,y) f(x,y)表示数对 ( x , y ) (x,y) (x,y)的欧几里得步数。
确定最大步数
由 f ( F i , F i + 1 ) = i f(F_i,F_{i+1})=i f(Fi,Fi+1)=i得:若 f ( x , y ) = i , x ≤ y f(x,y)=i,x\leq y f(x,y)=i,x≤y,则 x ≥ F i , y ≥ F i + 1 x\geq F_i,y\geq F_{i+1} x≥Fi,y≥Fi+1。
求解最优数对个数
结论:
- gcd ( x , y ) > 1 \gcd(x,y)>1 gcd(x,y)>1且 f ( x , y ) > 1 f(x,y)>1 f(x,y)>1的数对显然不优。所以特判最大步数为 1 1 1的情况,其余情况只需要考虑 gcd \gcd gcd为 1 1 1的数对。
- 定义数对 ( x , y ) (x,y) (x,y)是好的当且仅当不存在 x ′ < x , y ′ < y x'<x,y'<y x′<x,y′<y使得 f ( x ′ , y ′ ) > f ( x , y ) f(x',y')>f(x,y) f(x′,y′)>f(x,y),定义数对 ( x , y ) (x,y) (x,y)是优秀的当且仅当: f ( x , y ) = i → x , y ≤ F i + 2 + F i − 1 f(x,y)=i\to x,y\leq F_{i+2}+F_{i-1} f(x,y)=i→x,y≤Fi+2+Fi−1
- 显然答案就是好的数对的个数。且好的数对一步之后一定会变成优秀的。
证明:对于一个数对 f ( x , y ) = i , x ≤ y f(x,y)=i,x\leq y f(x,y)=i,x≤y,设 x ≥ F i , y > F i + 2 + F i − 1 x\geq F_i,y>F_{i+2}+F_{i-1} x≥Fi,y>Fi+2+Fi−1。设其由一个好的数对 ( a , b ) ( a = y , b = p y + x ) (a,b)(a=y,b=py+x) (a,b)(a=y,b=py+x), f ( a , b ) = i + 1 f(a,b)=i+1 f(a,b)=i+1,其中 a = y > F i + 2 + F i − 1 , b = p y + x ≥ y + x > F i + 3 a=y>F_{i+2}+F_{i-1},b=py+x\geq y+x> F_{i+3} a=y>Fi+2+Fi−1,b=py+x≥y+x>Fi+3,所以存在 x ′ = F i + 2 < a , y ′ = F i + 3 < b x'=F_{i+2}<a,y'=F_{i+3}<b x′=Fi+2<a,y′=Fi+3<b,满足 f ( x ′ , y ′ ) = i + 2 > f ( a , b ) f(x',y')=i+2>f(a,b) f(x′,y′)=i+2>f(a,b),故 ( a , b ) (a,b) (a,b)不是好的,矛盾。
于是可以找出所有优秀的数对 f ( x , y ) = i f(x,y)=i f(x,y)=i推出 f ( x ′ , y ′ ) = i + 1 f(x',y')=i+1 f(x′,y′)=i+1的好的数对。
优秀的数对每层都很少:最小的是 ( F i , F i + 1 ) (F_i,F_{i+1}) (Fi,Fi+1),会产生2,3个答案,其它都只产生一个答案,总共是 log \log log级别的, 预处理出来即可。
copied by WerKeyTom_FTD
#include<cstdio>
#include<algorithm>
#include<vector>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pi;
const int mx=90+10,mo=1000000007;
const ll inf=1000000000000000000;
ll fib[mx];
vector<pi> a[mx];
vector<pi>::iterator it;
ll x,y,n,m,num;
int i,j,k,l,t,tot,ca,ans;
int main(){
fib[0]=fib[1]=1;
tot=1;
while (1){
fib[tot+1]=fib[tot]+fib[tot-1];
if (fib[tot+1]>inf) break;
tot++;
}
a[1].pb(mp(1,2));a[1].pb(mp(1,3));a[1].pb(mp(1,4));
fo(i,1,tot-3){
it=a[i].begin();
while (it!=a[i].end()){
x=(*it).xx;y=(*it).yy;
x+=y;
while (x<=fib[i+3]+fib[i]){
a[i+1].pb(mp(y,x));
x+=y;
}
it++;
}
}
scanf("%d",&ca);
while (ca--){
scanf("%lld%lld",&n,&m);
if (n>m) swap(n,m);
ans=1;
while (fib[ans+1]<=n&&fib[ans+2]<=m) ans++;
printf("%d ",ans);
if (ans==1){
printf("%lld\n",n*m%mo);
continue;
}
else{
num=0;
it=a[ans-1].begin();
while (it!=a[ans-1].end()){
x=(*it).xx;y=(*it).yy;
if (y<=n) (num+=(m-x)/y)%=mo;
if (y<=m) (num+=(n-x)/y)%=mo;
it++;
}
printf("%d\n",num);
}
}
}