zoukankan      html  css  js  c++  java
  • loj#3312. 「ZJOI2020」传统艺能

    题目描述

    题解

    签到题,比T3不知道阳间到哪里去了

    分开计算每个区间的答案,一次修改对于一个区间有5种情况:

    ①没有任何影响,即在父亲区间外

    ②使当前区间直接覆盖

    ③使当前区间及祖先区间清空

    ④覆盖祖先区间

    ⑤把祖先区间的标记传到当前区间

    分别算出五种情况的概率(相加要为1),设dpf[i][0/1/2]表示当前及祖先区间无标记,祖先区间有标记,当前区间有标记,矩乘加速

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define add(a,b) a=((a)+(b))%998244353
    #define mod 998244353
    #define Mod 998244351
    #define ll long long
    //#define file
    using namespace std;
    
    struct mat{ll a[3][3];void clear() {memset(a,0,sizeof(a));}} a,b,aI;
    mat mul(mat &a,mat b)
    {
    	static mat c;
    	int i,j,k,l;
    	
    	fo(i,0,2)
    	{
    		fo(j,0,2)
    		{
    			c.a[i][j]=0;
    			fo(k,0,2)
    			add(c.a[i][j],a.a[i][k]*b.a[k][j]);
    		}
    	}
    	a=c;
    }
    
    int m,i,j,k,l;
    ll n,ans,N,Ny;
    set<int> st;
    set<int> :: iterator I,J;
    
    ll qpower(ll a,int b) {ll ans=1; while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
    void js(ll fx,ll fy,ll x,ll y)
    {
    	ll s0=((fx-1)*fx/2+(n-fy)*(n-fy+1)/2)%mod,s1=((x-fx)*(n-y+1)+(fy-y)*x)%mod,s2=((y-x+1)*n-(y-x+1)*(y-x+2)/2+(y-x+1)-(n-y+1)-x+1)%mod,
    	s3=(fx*(n-fy+1))%mod,s4=((x-fx)*(fx-1)+(x-fx)*(x-fx+1)/2+(fy-y)*(n-fy)+(fy-y)*(fy-y+1)/2)%mod;
    	s0=s0*Ny%mod;s1=s1*Ny%mod;s2=s2*Ny%mod;s3=s3*Ny%mod;s4=s4*Ny%mod;
    	int i;
    	
    	i=m;a=aI;b.clear();
    	add(b.a[0][0],s0),add(b.a[1][1],s0),add(b.a[2][2],s0);
    	add(b.a[0][2],s1),add(b.a[1][2],s1),add(b.a[2][2],s1);
    	add(b.a[0][0],s2),add(b.a[1][0],s2),add(b.a[2][0],s2);
    	add(b.a[0][1],s3),add(b.a[1][1],s3),add(b.a[2][2],s3);
    	add(b.a[0][0],s4),add(b.a[1][2],s4),add(b.a[2][2],s4);
    	while (i)
    	{
    		if (i&1) mul(a,b);
    		mul(b,b);i>>=1;
    	}
    	add(ans,a.a[0][2]);
    }
    
    int main()
    {
    	#ifdef file
    	freopen("loj3312.in","r",stdin);
    	#endif
    	
    	scanf("%lld%d",&n,&m);st.insert(1);st.insert(n+1);N=(n*(n+1)/2)%mod;Ny=qpower(N,Mod);aI.a[0][0]=aI.a[1][1]=aI.a[2][2]=1;
    	ans=Ny;
    	fo(i,1,n-1)
    	{
    		scanf("%d",&j);
    		J=st.upper_bound(j);I=J;--I;
    		js(*I,(*J)-1,*I,j);
    		js(*I,(*J)-1,j+1,(*J)-1);
    		st.insert(j+1);
    	}
    	printf("%lld
    ",(ans+mod)%mod);
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    Python使用requests发送请求
    Python安装requests
    Python Windows开发环境搭建
    django学习笔记urls(1)
    Spring boot activiti工作流,权限管理框架
    Redis入门实战(7)-SpringDataRedis操作redis
    Redis入门实战(6)-Redisson操作redis
    Redis入门实战(5)-lettuce操作redis
    Redis入门实战(4)-Jedis操作redis
    Redis入门实战(3)-命令行
  • 原文地址:https://www.cnblogs.com/gmh77/p/13225665.html
Copyright © 2011-2022 走看看