• 绵阳东辰国际test201910.25


    T1

    分析:

    其中d(重要程度)一定是单调不升的,

    所以对于选的顺序一定是按顺序来的,除非有一段相等

    然后就乱搞就行了

    code by wzxbeliever:

    #include<bits/stdc++.h>
    #define ll long long
    #define il inline
    #define ri register int
    #define lowbit(x) x&(-x)
    using namespace std;
    const int maxn=1e5+5;
    int n,cnt,last,sum,up;
    int ans[maxn]; 
    int a[maxn];
    int main(){
    	scanf("%d",&n);
    	for(ri i=1;i<=n;i++)scanf("%d",&a[i]);
        int now=1;
    	while(a[now]!=n)now++;
    	ans[++cnt]=now;
    	last=n-now+1;
        for(ri i=now+1;i<=n;i++){
        int pos;
    	if(a[i]!=last-1){
        	pos=i;
        	while(a[pos]!=last-1)pos++;
        	ans[++cnt]=pos-i+1;
        	last=a[i];
    		i=pos;
    	}
    	else ans[++cnt]=1,last=a[i];
        }
        sum=cnt;up=sum+1;
        for(ri i=cnt;i>=1;i--){
        	printf("%d ",sum);sum--;
        	for(ri j=2;j<=ans[i];j++)
        	printf("%d ",up),up++;
    	}
    	return 0;
    }
    
    

    T2

    分析:

    考试的时候想到用并查集,但就是不知道怎么合并

    对于每个询问,转化为询问动物还存活的概率

    因为赢得情况很多(石头>剪刀>布>石头),但赢的概率是一定的

    如果它在主场就有2/3的概率获胜,

    而如果它在客场就只有1/3的概率获胜

    假如现在我们要合并(u,v)两个笼子

    u是主场,v是客场

    假如动物j,以前就有概率存活在u,且概率为x,那么合并后它还存活的概率就位2x/3

    同理客场为x/3

    考虑用并查集维护信息

    合并的时候要将u中所有的都乘上2/3

    将v中所有的都乘上1/3

    具体就是再打一个标记

    合并和路径压缩的时候就对应的修改

    code by std:

    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <deque>
    #include <queue>
    #include <vector>
    #include <set>
    const int N=210000;
    const int mo=998244353;
    const int w1=(mo+1)/3;
    int n,m,father[N],w[N];
    int quick(int k1,int k2){
    	int k3=1;
    	while (k2){
    		if (k2&1) k3=1ll*k3*k1%mo;
    		k2>>=1; k1=1ll*k1*k1%mo;
    	}
    	return k3;
    }
    int merge(int k1,int k2){
    	father[k1]=k2; w[k1]=1ll*w[k1]*quick(w[k2],mo-2)%mo;
    }
    int findfather(int k1){
    	if (father[k1]==k1) return k1;
    	int f=findfather(father[k1]); 
    	if (f!=father[k1]) w[k1]=1ll*w[k1]*w[father[k1]]%mo;
    	return father[k1]=f;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++) father[i]=i,w[i]=1;
    	int tot=1;
    	for (int i=1;i<=n;i++) tot=3ll*tot%mo;
    	for (int i=1;i<=m;i++){
    		int ty,k1,k2; 
    		scanf("%d%d",&ty,&k1);
    		if (ty==1){
    			scanf("%d",&k2);
    			k1=findfather(k1); k2=findfather(k2);
    			w[k1]=2ll*w[k1]*w1%mo; w[k2]=1ll*w[k2]*w1%mo;
    			merge(k1,k2);
    		} else {
    			int k2=findfather(k1);
    			int ans=1ll*tot*w[k1]%mo;
    			if (k1!=k2) ans=1ll*ans*w[k2]%mo;
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
    

    结论题:

    求树的最大独立集有一个贪心的做法.

    每轮选择所有叶子,将它们加入答案,并将这些叶子和它们的父亲删掉****,进入下一轮.

    于是只需要判断上一次的树的根节点是被删掉的,还是被它的某些儿子去掉的.

    code by std:

    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    using namespace std;
    const int N=110000,mo=998244353;
    struct bian{
    	int next,point;
    }b[N<<1];
    int p[N],len,n,m;
    void ade(int k1,int k2){
    	b[++len]=(bian){p[k1],k2}; p[k1]=len;
    }
    void add(int k1,int k2){
    	ade(k1,k2); ade(k2,k1);
    }
    int f[N],num,u[N];
    void dfs(int k1,int k2){
    	f[k1]=1;
    	for (int i=p[k1];i;i=b[i].next){
    		int j=b[i].point;
    		if (j!=k2){
    			dfs(j,k1); f[k1]&=(1-f[j]);
    		}
    	}
    	num+=f[k1];
    }
    void dfs1(int k1,int k2){
    	int tot=0;
    	for (int i=p[k1];i;i=b[i].next){
    		int j=b[i].point;
    		if (j!=k2) tot+=f[j];
    	}
    	for (int i=p[k1];i;i=b[i].next){
    		int j=b[i].point;
    		if (j!=k2){
    			if (u[k1]) u[j]=0; else u[j]=(tot==f[j]);
    			dfs1(j,k1);
    		}
    	}
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<n;i++){
    		int k1,k2; scanf("%d%d",&k1,&k2);
    		add(k1,k2);
    	}
    	dfs(1,0); dfs1(1,0);
    	int ans=num; printf("%d
    ",ans); int tag=f[1];
    	for (;m;m--){
    		int k1; scanf("%d",&k1);
    		ans=1ll*ans*n%mo;
    		if (tag==0){
    			ans=(ans+num)%mo; tag=f[k1]&&(u[k1]==0);
    		} else tag=0;
    		printf("%d
    ",ans);
    	}
    }
    
    
  • 相关阅读:
    rsync命令
    乱七八糟
    MeterSphere源码在windows部署
    测试使用——弱网测试用例与工具
    测试知识——测试左移与测试右移的理解与实践
    测试知识——测试左移右移,测试人员往哪里移?
    测试知识——了解全链路压测
    测试知识——接口测试测什么?
    MQTT客户端(c#)
    FreeRTOS 启动流程
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11741192.html
Copyright © 2020-2023  润新知