sol:笛卡尔树模板题,笛卡尔树的介绍可以参考 http://memphis.is-programmer.com/posts/46317.html。
code:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
struct node{
int k,id,p,val;
int ch[2];
}tr[maxn];
bool cmp1(node& a,node& b){
return a.k<b.k;
}
bool cmp2(node& a,node& b){
return a.id<b.id;
}
int sta[maxn];
int top,rt;
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&tr[i].k,&tr[i].val);
tr[i].id = i;
}
sort(tr+1,tr+n+1,cmp1);
for(int i=1;i<=n;i++){
int rs = 0;
while(top&&tr[sta[top]].val>tr[i].val){
int u = sta[top];
tr[u].ch[1] = rs;
tr[rs].p = u;
rs = u;
tr[i].ch[0]=u;
tr[u].p = i;
top--;
}
if(top) {
tr[sta[top]].ch[1]=i;
tr[i].p = sta[top];
}
sta[++top]=i;
}
for(int i=1;i<=n;i++) {
if(tr[i].p) tr[i].p = tr[tr[i].p].id;
if(tr[i].ch[0]) tr[i].ch[0] = tr[tr[i].ch[0]].id;
if(tr[i].ch[1]) tr[i].ch[1] = tr[tr[i].ch[1]].id;
}
sort(tr+1,tr+n+1,cmp2);
puts("YES");
for(int i=1;i<=n;i++){
// cout<<i<<" ------\n";
printf("%d %d %d\n",tr[i].p,tr[i].ch[0],tr[i].ch[1]);
}
return 0;
}
HDU6305(多校第一场)题目链接
sol:
按照dls的讲解,RMQsimilar的实质就是两棵树的笛卡尔树同构。构建出A的笛卡尔树,那么随机生成的01序列与A同构的概率即为 (sz[i]为笛卡尔树中以i为根的子树大小),根据直觉, = n/2,相乘即为答案。
code:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e6+10;
const int mod = 1e9+7;
#define PII pair<int,int>
#define fi first
#define se second
ll inv[maxn];
int sta[maxn],ch[maxn][2];
int top,rt,n;
PII a[maxn];
ll ans;
void get_inv(){
inv[1]=1;
for(int i=2;i<maxn;i++) inv[i] = inv[mod%i]*(mod-mod/i)%mod;
}
void build(){
rt = top = 0;
for(int i=1;i<=n;i++){
int rs = 0;
while(top&&a[sta[top]]<a[i]){
ch[sta[top]][1]= rs;
rs = sta[top];
ch[i][0] = sta[top];
top--;
}
if(top) ch[sta[top]][1] = i;
else rt = i;
sta[++top]=i;
}
}
int dfs(int u){
if(u==0) return 0;
int sz = 1;
sz+=dfs(ch[u][0]);
sz+=dfs(ch[u][1]);
(ans*=inv[sz])%=mod;
return sz;
}
int main(){
get_inv();
int T;
scanf("%d",&T);
while(T--){
for(int i=1;i<=n;i++) ch[i][0]=ch[i][1]=0;
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%d",&a[i].fi);
a[i].se = -i;
}
build();
ans = 1;
dfs(rt);
ans = ans*inv[2]%mod*n%mod;
printf("%lld\n",ans);
}
return 0;
}