csps模拟测试74梦境,玩具,飘雪圣域题解

题面:https://www.cnblogs.com/Juve/articles/11679226.html

梦境:

其实还是挺水的,排序错了过不了样例,打了个二分图匹配就跑了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<set>
 6 #define int long long
 7 using namespace std;
 8 const int MAXN=2e5+5;
 9 int n,m,b[MAXN],ans=0;
10 struct node{
11     int l,r;
12     friend bool operator < (node p,node q){
13         return p.r==q.r?p.l<q.l:p.r<q.r;
14     }
15 }a[MAXN];
16 multiset<int>s;
17 signed main(){
18     scanf("%lld%lld",&n,&m);
19     for(int i=1;i<=n;++i)
20         scanf("%lld%lld",&a[i].l,&a[i].r);
21     sort(a+1,a+n+1);
22     for(int i=1;i<=m;++i){
23         scanf("%lld",&b[i]);
24         s.insert(b[i]);
25     }
26     for(int i=1;i<=n;++i){
27         multiset<int>::iterator it=s.lower_bound(a[i].l);
28         if(it!=s.end()&&(*it)<=a[i].r){
29             ++ans;
30             s.erase(it);
31         }
32     }
33     printf("%lld\n",ans);
34     return 0;
35 }
View Code

玩具:神仙dp,

颓的题解和方程

令f[i][j]表示有i个点的树,深度不超过j的概率,g[i][j]表示有i个点的森林,深度不超过j的概率,

f[i][j]=g[i-1][j-1](j!=0) f[0][1]=1;

$g[i][j]=\sum\limits_{k=1}^{i}f[k][j]*g[i-k][j]*inv[i]$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 using namespace std;
 7 const int MAXN=205;
 8 int n,mod,inv[MAXN],ans=0,g[MAXN][MAXN],f[MAXN][MAXN];
 9 signed main(){
10     scanf("%lld%lld",&n,&mod);
11     inv[0]=inv[1]=1;
12     for(int i=2;i<=n;++i) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
13     for(int i=0;i<=n;++i) g[0][i]=1;
14     for(int i=1;i<=n;++i){
15         for(int j=0;j<=n;++j){
16             if(j) f[i][j]=g[i-1][j-1];
17             else if(i==1)  f[i][j]=1;
18             for(int k=1;k<=i;++k)
19                   g[i][j]=(g[i][j]+1ll*f[k][j]*g[i-k][j]%mod*inv[i]%mod)%mod;
20         }
21     }
22     for(int i=1;i<=n;++i){
23         ans=(ans+1ll*(f[n][i]-f[n][i-1]+mod)%mod*i%mod)%mod;
24     }
25     printf("%lld\n",ans);
26     return 0;
27 }
View Code

飘雪圣域:

主席树,树状数组,莫队都可以过

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define re register
using namespace std;
const int MAXN=2e5+5;
int n,q;
vector<int>mp[MAXN];
int tot=0,root[MAXN];
struct node{
	int ls,rs,val;
}tr[MAXN*30];
void build(int &k,int l,int r){
	k=++tot;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(tr[k].ls,l,mid);
	build(tr[k].rs,mid+1,r);
}
void insert(int &now,int pre,int l,int r,int pos){
	now=++tot;
	tr[now]=tr[pre],++tr[now].val;
	if(l==r) return ;
	int mid=(l+r)>>1;
	if(pos<=mid) insert(tr[now].ls,tr[pre].ls,l,mid,pos);
	else insert(tr[now].rs,tr[pre].rs,mid+1,r,pos);
}
int query(int x,int y,int l,int r,int opl,int opr){
	if(opl<=l&&r<=opr) return tr[y].val-tr[x].val;
	int mid=(l+r)>>1,res=0;
	if(opl<=mid) res+=query(tr[x].ls,tr[y].ls,l,mid,opl,opr);
	if(opr>mid) res+=query(tr[x].rs,tr[y].rs,mid+1,r,opl,opr);
	return res;
}
signed main(){
	scanf("%d%d",&n,&q);
	for(int i=1,u,v;i<n;++i){
		scanf("%d%d",&u,&v);
		mp[min(u,v)].push_back(max(u,v));
	}
	for(int i=1;i<=n;++i){
		root[i]=root[i-1];
		int N=mp[i].size();
		for(int j=0;j<N;++j){
			insert(root[i],root[i],1,n,mp[i][j]);
		}
	}
	while(q--){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",r-l+1-query(root[l-1],root[r],1,n,l,r));
	}
	return 0;
}

 

posted @ 2019-10-15 17:53  xukl21  阅读(177)  评论(0编辑  收藏  举报