• 正睿OI国庆day1


    正睿OI国庆day1

    T1

    [ S_n=1*S_{n-1}+1*F_{n-1}+1*F_{n-2}+1*f_{n-1}+1*f_{n-2} ]
    [ F_{n}=0*S_{n-1}+1*F_{n-1}+1*F_{n-2}+1*f_{n-1}+1*f_{n-2} ]
    [ F_{n-1}=0*S_{n-1}+1*F_{n-1}+0*F_{n-2}+0*f_{n-1}+0*f_{n-2} ]
    [ f_n=0*S_{n-1}+0*F_{n-1}+0*F_{n-2}+1*f_{n-1}+1*f_{n-2} ]
    [ f_{n-1}=0*S_{n-1}+0*F_{n-1}+0*F_{n-2}+1*f_{n-1}+0*f_{n-2} ]

    矩阵:(要竖过来)

    $1 1 1 1 1$

    $0 1 1 1 1$

    $0 1 0 0 0$

    $0 0 0 1 1$

    $0 0 0 1 0$

    矩阵乘法O(logn)求得

    好像可以生成函数搞,晚上学一下

    (f'n=frac{x}{1-x-x^2})

    (F'x=f'^2x)

    (G'x=F'xfrac{1}{1-x})

    其中$'$是上尖号

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define ll long long
    ll read(){
    	ll x=0,pos=1;char ch=getchar();
    	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
    	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    	return pos?x:-x;
    } 
    ll n;
    struct node{
    	ll g[5][5];
    }ori,f1,f2;
    const ll mod=998244353;
    node mul(node a,node b){
    	node c;memset(c.g,0,sizeof(c.g));
    	for(int i=0;i<=4;i++){
    		for(int j=0;j<=4;j++){
    			for(int k=0;k<=4;k++){
    				c.g[i][j]=(c.g[i][j]+(a.g[i][k]*b.g[k][j])%mod);
    				if(c.g[i][j]>=mod) c.g[i][j]-=mod;
    			}
    		}
    	}
    	return c;
    }
    node ksm(node a,ll b){
    	node res=ori;
    	while(b){
    		if(b&1){
    			res=mul(res,a);
    		}
    		b>>=1;
    		a=mul(a,a);
    	}
    	return res;
    }
    int main(){
    	n=read();n++;
    	if(n==1){
    		printf("1");
    		return 0;
    	}
    	if(n==2){
    		printf("3");
    		return 0;
    	}
    	memset(ori.g,0,sizeof(ori.g));
    	ori.g[0][0]=1;
    	ori.g[1][1]=1;
    	ori.g[2][2]=1;
    	ori.g[3][3]=1;
    	ori.g[4][4]=1;
    	ori.g[5][5]=1;
    	memset(f1.g,0,sizeof(f1.g));
    	f1.g[0][0]=1;
    	f1.g[1][0]=1;
    	f1.g[1][1]=1;
    	f1.g[1][2]=1;
    	f1.g[2][0]=1;
    	f1.g[2][1]=1;
    	f1.g[3][0]=1;
    	f1.g[3][1]=1;
    	f1.g[3][3]=1;
    	f1.g[3][4]=1;
    	f1.g[4][0]=1;
    	f1.g[4][1]=1;
    	f1.g[4][3]=1;
    	node s=ksm(f1,n-2);
    	printf("%lld",(s.g[0][0]*3%mod+s.g[1][0]*2%mod+s.g[2][0]+s.g[3][0]+s.g[4][0])%mod);
    	return 0;
    }
    

    T2

    考虑换根的时候一部分答案不变

    处理最大值和次大值

    dfs更新答案就行了

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    using namespace std;
    int read(){
    	int x=0,pos=1;char ch=getchar();
    	for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
    	for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
    	return pos?x:-x;
    } 
    const int N = 200001;
    int f[N][20];
    struct node{
    	int v,nex,w;
    }edge[N];
    int head[N],top=1,n,m,dep[N],c[N],cnt[N],fa[N];
    ll ans[N],g[N][2],tot;
    inline void add(int u,int v){
    	edge[++top].v=v;
    	edge[top].nex=head[u];
    	head[u]=top;
    }
    void dfs1(int now,int pre){
    	f[now][0]=pre;
    	dep[now]=dep[pre]+1;
    	for(int i=1;i<=18;i++){
    		f[now][i]=f[f[now][i-1]][i-1];
    	}
    	for(int i=head[now];i;i=edge[i].nex){
    		int v=edge[i].v;
    		if(v!=f[now][0]) dfs1(v,now);
    	}
    }
    int get_lca(int u,int v){
    	if(dep[u]<dep[v]) swap(u,v);
    	for(int i=18;i>=0;i--){
    		if(dep[f[u][i]]>=dep[v]) u=f[u][i];
    	}
    	if(u==v) return u;
    	for(int i=18;i>=0;i--){
    		if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
    	}
    	return f[u][0];
    }
    void dfs2(int now){
    	for(int i=head[now];i;i=edge[i].nex){
    		int v=edge[i].v;
    		if(v!=f[now][0]){
    			dfs2(v);
    			cnt[now]+=cnt[v];
    			if(cnt[v]>=g[now][0]){
    				g[now][1]=g[now][0];
    				g[now][0]=cnt[v];
    			}else if(cnt[v]>g[now][1]){
    				g[now][1]=cnt[v];
    			}
    			ans[1]+=cnt[v];
    		}
    	}
    	cnt[now]+=c[now];
    	ans[1]-=g[now][0];
    }
    long long re=0;
    void dfs3(int now){
    	for(int i=head[now];i;i=edge[i].nex){
    		int v=edge[i].v;
    		if(v==f[now][0]) continue;
    		ans[v]=ans[now];
    		if(cnt[v]==g[now][0]){
    			ans[v]+=(g[now][0]-g[now][1]);
    		}
    		if(cnt[v]>g[v][0]){
    			ans[v]-=(cnt[v]-g[v][0]);g[v][1]=g[v][0];g[v][0]=cnt[v];
    		}else if(cnt[v]>g[v][1]) g[v][1]=cnt[v];
    		dfs3(v);
    	}
    	re=min(re,ans[now]);
    }
    int main(){
    	re=19280817000000ll;
    	n=read(),m=read();
    	for(int i=1,u,v;i<n;i++){
    		u=read(),v=read();
    		add(u,v);
    		add(v,u);
    	}
    	dfs1(1,0);
    	for(int u,v,i=1;i<=m;i++){
    		u=read(),v=read();
    		int lca=get_lca(u,v);
    		c[u]++;c[v]++;c[lca]-=2;
    	}
    	dfs2(1);
    	dfs3(1);
    	printf("%lld",re);
    	return 0;
    }
    

    T3

    (f(i,S,M) ---- f(i+1,S+1,max(M,g(a_i,b_i))))

    转移过程是获胜事件的发生概率

  • 相关阅读:
    461.mysql数据的备份和恢复
    thinkcmf安装遇到的问题【服务器rewrite】未开启
    navicat for mysql 中文破解版(无需激活码)
    centos7--docker安装gitlab时权限异常
    Cenos7 ++Zabbix监控(同个节点)
    Centos-第一次机子遭受黑客入侵??很鸡冻
    Linux运维--企业sudo权限规划详解 (实测一个堆命令搞定)
    Centos7--sudo的使用和配置
    网络技术--IPv4子网掩码的理解和计算。
    CentOS7--部署JSP网站项目(环境架构jsp+mysql+tomcat)
  • 原文地址:https://www.cnblogs.com/lcyfrog/p/11615590.html
Copyright © 2020-2023  润新知