zoukankan      html  css  js  c++  java
  • CF掉分日记 6.6 6.8

    ---恢复内容开始---

      写的效果依旧不好 还没写完前四题比赛就结束了 而且这些普及组的题目 我大多还是缺少简单算法的灵性 总是把问题搞复杂化。

    6.5 A 第一道题非常水 简单分析发现是一个快速幂的逆过程。logn时间内解决。

          B 这是一个比平成的模拟要难上一点点的 模拟 因为有可能爆ll 所以写之前要把该考虑到的情况考虑好再写。

          C 一眼不可做 也看不懂题目是什么意思,还是看不懂弃掉以后看见了再写https://codeforces.com/contest/1175/problem/C

       D 感觉能写 一段序列分成k段 第一段乘1 第二段乘2... 求最大值 显然dp 然后 f[i][j] 表示前 i个数字分成j段的最大值 这个dp 是n^2k的相当难受 貌似斜率优化可以到nk 然后? 然后还是挂掉。

    乱搞出来一个贪心 是 我从后往前拿第k 段 k-1段 每次我都选取最大的那个后缀和 nlogn 发现一直wa 没有考虑到一些因素并不是后缀和最大的是最优的因为当前数字造成的贡献不只只有前面的而且还是有后面的,所以说不太会写,考虑设p1 p2 ...pk 为每一段的断点 显然p1=1; pi<pi+1 取bi为 i~n的和 也就是后缀和 那么此时sum=1*(bp1-bp2)+2*(bp2-bp3)+..k*bk; 得到.bp1 + bp2 + bp3 + bp4 ... bpk;

    发现我们只需取最大的这几个bp值即可 注意p1是强制取1的。

    剩下的题目没看结束了。。。

    6.8 A 是一道非常水的题目注意好关系就能AC

          B 猛一看感觉是不可写的 但是实际上画个图发现每次放棋子只能放在上一个棋子的 右边 或者下边注意维护好轮换放即可。

          C 是一道比较有意思的题目 看起来也不可做深入理解发现只会有两种情况 1 枚举每次放哪个数字了如果当前手牌中没有的话就一直取数字直至把这个数字取出来 然后模拟放回去。

          或者是 在这个队伍之中就直接模拟排序好 如果可以成功那么一定优于第一种决策。这样就OK了!

          D 好像是一个排列计数 看了一下不会写弃掉了现在再看 n<=2e5 看完题解 发现是一个很妙的树形dp
    题目:https://codeforces.com/contest/1173/problem/D

    哦 原来是这样的 对于一个无根树来说我们以任意的角度来看的话我们可以想象成每个点都可以是根,所以 可以以1为根 然后发现 1 任何位置都是可以放的。

    考虑1的子树 由于子树必须是在一个圆弧之上 显然 。 所以子树们和父亲们放的位置决定了父亲的初始方案数 仔细思考1可以放n个位置我们让其按照一个方式放的话也把所有方案数遍历到了。

    好题 于是就有转移了。下面放代码:

    //#include<bits/stdc++.h>
    #include<iomanip>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<deque>
    #include<cmath>
    #include<ctime>
    #include<cstdlib>
    #include<stack>
    #include<algorithm>
    #include<vector>
    #include<cctype>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<map>
    #define INF 2147483646
    #define ll long long
    #define min(x,y) (x>y?y:x)
    #define max(x,y) (x>y?x:y)
    #define RI register ll
    #define up(p,i,n) for(ll i=p;i<=n;++i)
    #define db double
    #define mod 998244353
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void put(ll x)
    {
        x<0?x=-x,putchar('-'):0;
        int num=0;char ch[50];
        while(x)ch[++num]=x%10+'0',x/=10;
        num==0?putchar('0'):0;
        while(num)putchar(ch[num--]);
        putchar('
    ');return;
    }
    const int MAXN=200010;
    int n,len;
    ll fac[MAXN],sz[MAXN],f[MAXN];//f[i] 表示以i为根的子树内部的方案数
    int vis[MAXN];
    int lin[MAXN<<1],nex[MAXN<<1],ver[MAXN<<1];
    inline void add(int x,int y)
    {
        ver[++len]=y;
        nex[len]=lin[x];
        lin[x]=len;
    }
    inline void dfs(int x)
    {
        vis[x]=1;sz[x]=1;ll sum=1;
        for(int i=lin[x];i;i=nex[i])
        {
            int tn=ver[i];
            if(vis[tn])continue;
            dfs(tn);sum=sum*f[tn]%mod;
            ++sz[x];
        }
        //f[x]=fac[sz[x]];
        if(x!=1)f[x]=fac[sz[x]];
        else f[x]=fac[sz[x]-1];
        f[x]=f[x]*sum%mod;
    }
    int main()
    {
        //freopen("1.in","r",stdin);
        n=read();fac[0]=1;
        for(int i=1;i<n;++i)
        {
            int x,y;
            x=read();y=read();
            add(x,y);add(y,x);
        }
        for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i%mod;
        dfs(1);
        put(f[1]*n%mod);
        return 0;
    }
    View Code

    剩下的题目就不说了。。不太会写也没有时间了。

  • 相关阅读:
    Benchmark Web App 性能瓶颈分析与性能测试工具的使用方法总结
    如何永久删除git仓库中敏感文件的提交记录
    javascript中的this在不同场景下的区别
    利用jsPDF有效减轻报表型应用服务器的IO负载
    nginx与apache的参考配置
    统计学中相关数学符号、希腊字母的标准读法
    C++的子类与父类强制转换产生的问题
    获得潜在新用户联系方式的妙招
    团队工作效率分析工具gitstats
    你被R语言的=和<-搞昏了头吗
  • 原文地址:https://www.cnblogs.com/chdy/p/10993226.html
Copyright © 2011-2022 走看看