zoukankan      html  css  js  c++  java
  • [ZJOI2020]传统艺能

    https://www.luogu.com.cn/blog/Thinking/solution-p6630
    把节点分为五类
    1.不会进入o的父亲且不在祖先终止(与o父亲区间不交)
    2.在o打标记终止(包含o但不能包含o的父亲)
    3.标记了o的祖先(包含o父亲)
    4.下推了o父亲标记但没进入o(与o兄弟有交但与o不交)
    5.进入o

    记录(f_i)表示(i)有标记概率 (g_i)表示(i)祖先(含(i))有标记概率 矩阵快速幂

    #include<bits/stdc++.h>
    using namespace std;
    #define fp(i,l,r) for(register int (i)=(l);i<=(r);++(i))
    #define fd(i,l,r) for(register int (i)=(l);i>=(r);--(i))
    #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next)
    #define mem(a) memset((a),0,sizeof (a))
    #define O(x) cerr<<#x<<':'<<x<<endl
    #define int long long
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    void wr(int x){
    	if(x<0)putchar('-'),x=-x;
    	if(x>=10)wr(x/10);
    	putchar('0'+x%10);
    }
    const int mod=998244353;
    inline void tmod(int &x){x%=mod;}
    inline int qpow(int a,int b){
    	int res=1;a%=mod;
    	for(;b;b>>=1,tmod(a*=a))
    		if(b&1)tmod(res*=a);
    	return res;
    }
    inline int ginv(int x){return qpow(x,mod-2);}
    struct Mat{
    	int a11,a12,a13,a22,a23;
    	inline Mat operator*(const Mat &b)const{
    		return {a11*b.a11%mod,(a11*b.a12+a12*b.a22)%mod,(a11*b.a13+a12*b.a23+a13)%mod,
    				a22*b.a22%mod,(a22*b.a23+a23)%mod};
    	}
    };
    int ans,inv,n,K;
    inline Mat qpow(Mat a,int b){
    	Mat res={1,0,0,1,0};
    	for(;b;b>>=1,a=a*a)
    		if(b&1)res=res*a;
    	return res;
    }
    void solve(int L,int R,int l,int r){
    	if(L<R){
    		int mid=read();
    		solve(L,mid,L,R);solve(mid+1,R,L,R);
    	}
    	if(!l)tmod(ans+=inv);
    	else{
    		int a=(l*(l-1)+(n-r)*(n-r+1)>>1)%mod,
    			b=(L*(r-R)+(n-R+1)*(L-l))%mod,
    			c=l*(n-r+1)%mod,
    			d=((l+L-1)*(L-l)+(n+n-R-r+1)*(r-R)>>1)%mod;
    		tmod(ans+=qpow({(a+c)*inv%mod,d*inv%mod,b*inv%mod,(a+d)*inv%mod,(b+c)*inv%mod},K).a13);
    	}
    }
    main(){
    	n=read();K=read();inv=ginv(n*(n+1)/2);
    	solve(1,n,0,0);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    linux(ubuntu) 安装 node.js
    正反向代理
    js正则表达式----replace
    webpack开发小总结
    稳定排序和非稳定排序
    树状数组 --- (离散化+树状数组、求逆序对)
    编程之美初赛第一场 题目3 : 活动中心
    巴什博弈 杭电 1847
    巴什博弈 杭电 1846
    约瑟夫环问题详解
  • 原文地址:https://www.cnblogs.com/WinterSpell/p/13274201.html
Copyright © 2011-2022 走看看