T1:
k
t
h
min
−
max
kth \min-\max
kthmin−max容斥后
一个集合期望为
(
n
+
1
2
)
w
,
w
\frac{{n+1\choose 2}}{w},w
w(2n+1),w是相交区间数
于是暴力
O
(
n
5
)
d
p
O(n^5)dp
O(n5)dp可过
f s y fsy fsy有神仙的四方做法但是我不会/kk
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
#define bg begin
namespace IO{
cs int RLEN=1<<20|1;
char ibuf[RLEN],*ib,*ob;
inline char gc(){
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=0;
while(!isdigit(ch))f=(ch=='-'),ch=gc();
while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
return f?-res:res;
}
}using IO::read;
template<typename tp>inline void chemx(tp &a,tp b){return (a<b)?(a=b):0;}
template<typename tp>inline void chemn(tp &a,tp b){return (a>b)?(a=b):0;}
cs int mod=998244353;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a<b?a-b+mod:a-b;}
inline int mul(int a,int b){static ll r;r=(ll)a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int &a,int b){a=a<b?a-b+mod:a-b;}
inline void Mul(int &a,int b){static ll r;r=(ll)a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
cs int N=105;
char xx;
int c[N][N],f[N][N][N*N/2],n,m,iv[N*N],S[N];
char yy;
int main(){
n=read(),m=n-read()+1;
for(int i=0;i<N;i++){
c[i][i]=c[i][0]=1;
for(int j=1;j<i;j++)c[i][j]=add(c[i-1][j],c[i-1][j-1]);
}iv[0]=iv[1]=1;
for(int i=2;i<N*N;i++)iv[i]=mul(mod-mod/i,iv[mod%i]);
for(int i=0;i<N;i++)S[i]=(i*(i+1))>>1;
f[0][0][0]=1;
int sm=S[n],res=0;
for(int i=0;i<=n;i++)
for(int j=0;j<=i;j++)
for(int k=0,l=S[i];k<=l;k++)if(f[i][j][k]){
int vl=f[i][j][k];
int now=mul(vl,mul(c[j-1][m-1],mul(sm,iv[sm-k-S[n-i]])));
// cout<<now<<" "<<i<<" "<<j<<" "<<k<<'\n';
if((j+m)&1)Dec(res,now);else Add(res,now);
for(int p=i+1;p<=n;p++){
Add(f[p][j+1][k+S[p-i-1]],vl);
}
}cout<<res<<'\n';
}
T2:
考虑
f
[
u
]
f[u]
f[u]表示
u
u
u内全部分配好的方案数
那么对于经过
u
u
u的路径方案是路径所有点其余儿子的积
合法即
s
u
+
s
v
−
s
l
c
a
−
s
f
a
l
c
a
≥
0
s_u+s_v-s_{lca}-s_{fa_{lca}}\geq0
su+sv−slca−sfalca≥0
于是可以在
l
c
a
lca
lca线段树维护答案
继承重儿子的线段树再一个个暴力加轻儿子子树所有点
积可以每个点记一下前后缀
复杂度
O
(
n
l
o
g
2
n
)
O(nlog^2n)
O(nlog2n)
不知道为什么永远跑不过仲爺
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define y1 shinkle
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
return f?res:-res;
}
inline char readchar(){
char ch=gc();
while(isspace(ch))ch=gc();
return ch;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
s[top+1]='\0';return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
cs int mod=1e9+7;
inline int add(int a,int b){return (a+b)>=mod?(a+b-mod):(a+b);}
inline int dec(int a,int b){return (a<b)?(a-b+mod):(a-b);}
inline int mul(int a,int b){static ll r;r=(ll)a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){a=(a+b)>=mod?(a+b-mod):(a+b);}
inline void Dec(int &a,int b){a=(a<b)?(a-b+mod):(a-b);}
inline void Mul(int &a,int b){static ll r;r=(ll)a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(ll x){x%=mod;return (x<0)?x+mod:x;}
cs int N=1e5+5,INF=1e9;
int rt;
namespace Seg{
cs int N=::N*100;
int lc[N],rc[N],s[N],tag[N],tot;
inline int newnode(){
int u=++tot;tag[u]=1,lc[u]=rc[u]=s[u]=0;
return u;
}
inline void clear(){tot=rt=0;}
inline void pushnow(int u,int k){Mul(tag[u],k),Mul(s[u],k);}
inline void pushdown(int u){
if(tag[u]==1)return;
if(lc[u])pushnow(lc[u],tag[u]);
if(rc[u])pushnow(rc[u],tag[u]);
tag[u]=1;
}
#define mid ((l+r)>>1)
void ins(int &u,int l,int r,int p,int k){
if(!u)u=newnode();
pushdown(u);
Add(s[u],k);if(l==r)return;
(p<=mid)?ins(lc[u],l,mid,p,k):ins(rc[u],mid+1,r,p,k);
}
int qry(int u,int l,int r,int p){
if(!u||p<=l)return s[u];
pushdown(u);
if(p<=mid)return add(qry(lc[u],l,mid,p),s[rc[u]]);
return qry(rc[u],mid+1,r,p);
}
inline int query(int p){return qry(rt,-INF,INF,p);}
inline void insert(int p,int k){return ins(rt,-INF,INF,p,k);}
inline void update(int k){return pushnow(rt,k);}
#undef mid
}
using Seg::query;
using Seg::insert;
using Seg::update;
using Seg::clear;
vector<int> e[N];
int vl[N],n,siz[N],f[N],fa[N];
int l[N],r[N],son[N*3],pre[N*3],suf[N*3],dfn;
void dfs1(int u){
siz[u]=1;vl[u]+=vl[fa[u]];
for(int v:e[u])if(v!=fa[u]){
fa[v]=u,dfs1(v),siz[u]+=siz[v];
}
l[u]=r[u]=dfn+1;
for(int v:e[u])if(v!=fa[u]){
son[++r[u]]=v;
}r[u]++;dfn=r[u];
sort(son+l[u]+1,son+r[u],[](cs int &i,cs int &j){return siz[i]>siz[j];});
}
int tot;
pii p[N];
void collect(int u,int sm){
p[++tot]=pii(vl[u],mul(sm,pre[r[u]-1]));
for(int i=l[u];i<r[u];i++)
collect(son[i],mul(sm,mul(pre[i-1],suf[i+1])));
}
void dfs2(int u){
// cout<<"int "<<u<<'\n';
for(int i=l[u]+2;i<=r[u];i++)dfs2(son[i]),clear();
if(l[u]+1<r[u])dfs2(son[l[u]+1]);
pre[l[u]]=suf[r[u]]=1;
for(int i=l[u]+1;i<r[u];i++)pre[i]=mul(pre[i-1],f[son[i]]);
for(int i=r[u]-1;i>l[u];i--)suf[i]=mul(suf[i+1],f[son[i]]);
if(vl[u]-vl[fa[u]]>=0)Add(f[u],pre[r[u]-1]);
Add(f[u],mul(suf[l[u]+2],query(vl[fa[u]])));
// cout<<u<<" "<<vl[u]-vl[fa[u]]<<" "<<f[u]<<" "<<l[u]<<" "<<r[u]<<" "<<'\n';
for(int i=l[u]+2;i<r[u];i++){
tot=0;collect(son[i],1);
for(int j=1;j<=tot;j++){
if(p[j].fi>=vl[fa[u]])Add(f[u],mul(p[j].se,mul(pre[i-1],suf[i+1])));
Add(f[u],mul(suf[i+1],mul(p[j].se,query(vl[u]+vl[fa[u]]-p[j].fi))));
}
update(f[son[i]]);
for(int j=1;j<=tot;j++)insert(p[j].fi,mul(p[j].se,pre[i-1]));
}
insert(vl[u],pre[r[u]-1]);
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
int size=40<<20;//40M
//__asm__ ("movl %0, %%esp\n"::"r"((char*)malloc(size)+size));//调试用这个
__asm__ ("movq %0,%%rsp\n"::"r"((char*)malloc(size)+size));//提交用这个
n=read();
for(int i=1;i<=n;i++)vl[i]=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
e[u].pb(v),e[v].pb(u);
}dfs1(1);
dfs2(1);
cout<<f[1];exit(0);//必须用exit
return 0;
}
T3:
考虑把平面树除去根转对偶
就变成圆上
2
n
2n
2n个点匹配,路径不交,旋转同构
显然
b
u
r
n
s
i
d
e
burnside
burnside
不旋转即为卡特兰数
(
2
n
n
)
−
(
2
n
n
−
1
)
{2n\choose n}-{2n\choose n-1}
(n2n)−(n−12n)
对于奇数
n
−
1
2
\frac{n-1}{2}
2n−1为特殊的中心对称,单独算
否则枚举循环节大小
d
d
d,那么
2
d
2d
2d中任意
d
d
d个做左括号有唯一合法方案
然后就做完了
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair<int,int>
#define ll long long
#define y1 shinkle
#define fi first
#define se second
#define bg begin
namespace IO{
cs int RLEN=1<<20|1;
char ibuf[RLEN],*ib,*ob;
inline char gc(){
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
return f?res:-res;
}
inline char readchar(){
char ch=gc();
while(isspace(ch))ch=gc();
return ch;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
s[top+1]='\0';return top;
}
}
using IO::read;
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
int mod;
inline int add(int a,int b){return (a+b)>=mod?(a+b-mod):(a+b);}
inline int dec(int a,int b){return (a<b)?(a-b+mod):(a-b);}
inline int mul(int a,int b){static ll r;r=(ll)a*b;return (r>=mod)?(r%mod):r;}
inline void Add(int &a,int b){a=(a+b)>=mod?(a+b-mod):(a+b);}
inline void Dec(int &a,int b){a=(a<b)?(a-b+mod):(a-b);}
inline void Mul(int &a,int b){static ll r;r=(ll)a*b;a=(r>=mod)?(r%mod):r;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline int fix(ll x){x%=mod;return (x<0)?x+mod:x;}
cs int N=1e5+5;
int fac[N],ifac[N],phi[N],pr[N],tot;
bool vis[N];
inline void init(cs int n=N-5){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i])pr[++tot]=i,phi[i]=i-1;
for(int j=1;j<=tot&&i*pr[j]<=n;j++){
vis[i*pr[j]]=1;
if(i%pr[j]==0){
phi[i*pr[j]]=phi[i]*pr[j];break;
}
phi[i*pr[j]]=phi[i]*(pr[j]-1);
}
}
}
int n;
inline void init_fac(){
fac[0]=ifac[0]=1;
for(int i=1;i<N;i++)fac[i]=mul(fac[i-1],i);
ifac[N-1]=Inv(fac[N-1]);
for(int i=N-2;i;i--)ifac[i]=mul(ifac[i+1],i+1);
}
inline int C(int n,int m){return (n<m||n<0||m<0)?0:mul(fac[n],mul(ifac[m],ifac[n-m]));}
inline int Cat(int n){return dec(C(2*n,n),C(2*n,n-1));}
inline void solve(){
n=read()-1,mod=read();
init_fac();
int res=Cat(n);
if(n&1)Add(res,C(n,n/2));
for(int i=1;i<n;i++)if(n%i==0)Add(res,mul(C(2*i,i),phi[n/i]));
Mul(res,Inv(2*n));cout<<res<<'\n';return;
}
int main(){
#ifdef Stargazer
freopen("lx.in","r",stdin);
#endif
init();
int T=read();
while(T--)solve();
}