zoukankan      html  css  js  c++  java
  • 纪中集训2019.11.05

    A.小D与原题

    题目链接

    题意:

      有$n$个点,求$n-1$个完美匹配,且其中不出现相同的边。

      $nle 10^3$

    分析一:

      打暴力/手玩找到规律。

      把匹配放到方格图上,给属于同一个完美匹配的方格染上同样的颜色,发现两个性质:

      ①最后一列第一行填$n$,之后往下从小到大填完偶数,再从小到大填完奇数;

      ②$forall iin [1,n-1]$,从$(1,i+1)$开始往左下方填,要填$(j,0)$时,转到$(j,n-1)$继续。

      然后每个匹配$(x,y)$按照$x<y$输出即可。

    分析二:

      考虑对于第$i$组组完美匹配,我们可以让它的所有$n/2$个匹配的某种特征量都相同且为$i$。

      考虑令匹配$(x,y)$中$x+y=i$。这里为了避开主对角线,令点由$0sim n-1$标号,那么一组完美匹配有:

      ①所有$x+yequiv i (mod n-1),;0le x,y<\, n-1$;

      ②一个$2pequiv i (mod n-1)$。

      发现和分析一里的规律吻合。

    实现(100分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #define IL inline
    #define RG register
    using namespace std;
    const int N=1e3;
    
        int n;
    
    int main(){
        freopen("problem.in","r",stdin);
        freopen("problem.out","w",stdout);
    
        scanf("%d",&n);
        
        for(int i=1;i<n;i++){
            for(int j=0;j<n-1;j++){
                int k=(i+n-1-j)%(n-1);
                if(j==k)
                    printf("%d %d ",j+1,n);
                else
                if(j<k)
                    printf("%d %d ",j+1,k+1);
                
            }
            printf("
    ");
            
        }
    
        return 0;
    
    }
    View Code

    小结:

      精准分配的时候,可以运用这种“关联特征量”的思路。比如:电影院放映厅按照单双号将人群分流到两个大门,人们按照行号寻找座位。

      一句题外话:下午讲题(B组)的时候,没有投影分数榜,结果我莽上去讲“第一题的某种直观理解方法”(分析一),没有发现下面一片尴尬的沉默,直到讲解第四题的时候我才惊觉自己走错了片场。监介。

    B.小D与随机

    题目链接

    题意:

      给出一棵$n$个节点的有根树,点的权值序列$w{n}$是一个$1sim n$的排列。定义点$i$是“好点”意为,$w_i$在根到$i$的链上最大。假设某个确定排列会确定树上的$c$个“好点”,那么这个排列的贡献是$k^c$。给出$k$,求所有排列的贡献总和。对$998244353$取模。

      对于$20\%$的数据,$nle 20$。

      对于另$40\%$的数据,给出一条链。

      对于$100\%$的数据,$nle 5000$。

    分析一:

      考虑链上怎么做。

      $mathscr{OI\_Killer}$:打表找规律,很容易就找到了。我也没仔细证。

      花了$4h+$撕烤规律+推导然而还是没能找到推法的$mathtt{Hansue}$表示:这规律真$TM$难推导好吧。

      设$f_i$是$n=i$时的答案,那么$f_n=f_{n-1} imes (k+n-1)$,且$f_1=k$。

    实现(40分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #define IL inline
    #define RG register
    using namespace std;
    typedef long long LL;
    const int N=5000;
    const LL mod=998244353;
    
        int n;
        LL k;
    
    int main(){
        freopen("random.in","r",stdin);
        freopen("random.out","w",stdout);
    
        scanf("%d%lld",&n,&k);
        
        LL ans=k;
        for(int i=2;i<=n;i++)
            ans=ans*(k+i-1)%mod;
    
        printf("%lld",ans);
    
        return 0;
    
    }
    View Code

    小结:

      实在不行,打表找规律√

    C.小D与游戏

    题目链接

    题意:

      字符集为${a,b,c}$。对于一个字符串,定义一个操作是将其相邻某两个不同字符,替换成另一个字符。

      给出原串,求能够拓展出的字符串集的大小。

    分析:

      令$a=0,b=1,c=2$,设$g(s)=sumlimits_i s_i (mod 3)$,发现一个操作不会改变$g(s)$,且操作之后至少会有一组相邻的相同字符。

      那么所有长度以及$g()$相同的,且至少有一组相邻的相同字符的字符串,它们互相连通。

      那么一个不存在相邻相同字符的字符串,随意操作一次,就进入了上述连通块。

      现在撕烤如何计算长度为$n$,$g()$和给定串相同的答案。

      考虑递推计算,设$f[n][sum][c][p]$表示长度为$n$,$g()=sum$,末位字符是$c$,存在相邻相同字符的情况是$p$,那么$$f[i+1][(s0+k)\%3][k][p||(k==x)]+=f[i][s0][x][p]$$

      初值是$f[1][i][i][0]=1$。

    实现(100分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #define IL inline
    #define RG register
    using namespace std;
    typedef long long LL;
    const int N=2e5;
    const LL mod=998244353;
    
    IL bool insigma(char ch){
        return 'a'<=ch&&ch<='c';
    }
    
        int n,s[N+3];
    
    IL void init(){
        char ch;
        while(!insigma(ch=getchar()));
        s[n=0]=ch-'a';  n++;
        while(insigma(ch=getchar()))
            s[n++]=ch-'a';
    
    }
    
    IL bool check0(){
        for(int i=1;i<n;i++)
        if(s[i]!=s[i-1])
            return false;
        return true;
    }
    
    IL void sol1(){
        int ans;
        if(n==1)
            ans=1;
        else
        if(n==2)
            ans=2;
        else
        if(n==3){
            if(s[0]!=s[1]&&s[0]!=s[2]&&s[1]!=s[2])
                ans=3;
            else
            if(s[0]==s[1]||s[1]==s[2])
                ans=6;
            else
                ans=7;
                
        }
                
        printf("%d",ans);
        
    }
    
    IL bool check1(){
        for(int i=1;i<n;i++)
        if(s[i]==s[i-1])
            return true;
        return false;
    }
    
    IL void add(LL &x,LL y){
        x=(x+y)%mod;
    }
    
    IL int fsum(){
        int ret=0;
        for(int i=0;i<n;i++)
            ret=(ret+s[i])%3;
        return ret;
    }
    
        LL f[N+3][3][3][2];      
    
    IL void sol2(){
        for(int i=0;i<3;i++)
            f[1][i][i][0]=1;
        for(int i=1;i<n;i++)
            for(int s0=0;s0<3;s0++)
                for(int j=0;j<3;j++)
                    for(int k=0;k<3;k++)
                        for(int p=0;p<2;p++)
                            add(f[i+1][(s0+k)%3][k][p|(j==k)],f[i][s0][j][p]);
        
        LL ans=check1()?0:1;
        int sum=fsum();
        for(int i=0;i<3;i++)
            ans=(ans+f[n][sum][i][1])%mod;
        printf("%lld",ans);
        
    }
    
    int main(){
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
    
        init();
        
        if(check0())
            printf("1");
        else
        if(n<=3)
            sol1();
        else
            sol2();
    
        return 0;
    
    }
    View Code

    小结:

      又是一道结论题。

    当天总结:

      前一天晚上选好了机子,结果当天一早来发现有人,心态$--$。

      麻烦重重地再选了一台机子,发现忘记GMOJ密码,心态$--$。

      小机房窗帘坏了,阳光很大,刺眼睛,心态$--$。

      T1刚了将近两个小时忽然发现搞错题意,心态$--$。

      转而写T2发现暴力没分,心态$--$。

      赶时间码出T3暴力,心态$++$。

      开始对T1找规律。其实结束之前已经搞出$n=6$的答案,然而顺着小规律的蛛丝马迹,没有抓住那一点灵感。感慨错亿。

      心态调控还可以加强。

      思维再$Sharpen$,找到更多更好的灵感,同时不让它溜走。

  • 相关阅读:
    ProtoType Design Tools
    什么是publickeytoken及publickeytoken的作用
    Windows最高权限system帐户
    Q70 AV01本本安装MAC
    解决MDict3在PPC下乱码的问题
    QT_XSP.CPP
    QT_XSP.CPP
    SetupFactory脚本
    DVD IFO FILE HEADER
    SerialPort comstat is being used without defining
  • 原文地址:https://www.cnblogs.com/Hansue/p/11799179.html
Copyright © 2011-2022 走看看