• Codeforces Round #536 (Div. 2)


    前言

    如您所见这又是一篇咕了的文章,直接咕了10天

    好久没打CF了 所以还是个蓝名菜鸡

    机房所有人都紫名及以上了,wtcl

    这次前4题这么水虽然不知道为什么花了1h,结果不知道为什么搞到一半出锅了,后面直接unrated了qwq

    虽然如果是rated我就掉成newbie了

    A

    题意

    在一个矩阵中统计(a_{i,j}=a_{i-1,j-1}=a_{i-1,j+1}=a_{i+1,j-1}=a_{i+1,j+1}='X')

    题解

    sbt

    B

    题意

    有n种菜,每种菜有价格和数量,然后依次会来m个客人,依次服务每个客人,每个客人需要一定数量的某个菜,如果有就给他,如果他要的菜没有就每次给他最便宜的中编号最小的菜,如果没有菜他就吃菜不付钱.问每个人交多少钱

    题解

    用set维护菜,价格第一关键字,编号第二关键字,然后模拟

    C

    题意

    n个数(n为偶数),要分组,每组不少于两个数,每组价值为元素和的平方,求最小价值和

    题解

    显然两个数一组,同时显然排完序后每次从两边各拿一个数凑成一组

    D

    题意

    给一个图,从1号点出发遍历这个图(随便遍历),第一次走到某个点就把编号加入一个序列,问最小字典序序列

    题解

    不知道比NOIPD2T1水到哪去了

    显然要从能走到的没走过的点里选一个编号最小的走,用堆维护即可

    E

    题意

    有k个红包,每个可以在([l_i,r_i])时间里取到,如果取这个红包就得到一定收益,同时往后走直到(d_i+1)时刻才能继续取红包((l_ile r_ile d_i))

    现在贪心取红包,如果在某个时刻能取红包,那么就取价值最大中d最大的红包

    现在可以骚扰m次,在时刻x骚扰会导致x时刻无法取红包,问最少取多少收益

    题解

    这题就是个dp啊,为什么我不去做呢qwq

    首先因为(r_ile d_i),所以每个时间点取红包都是唯一的,不会相互影响.用set预处理出每个时间点取那个红包.可以发现每个红包可以看成一个([i,d_i])有收益的线段,然后可以插入m个长度为1收益为0线段,然后依次填满时间段,问最小代价.设(f[i][j])表示做到时刻i,骚扰j次,转移枚举下一位骚扰或不骚扰即可

    然而我做的时候各种细节没考虑,交了1h

    #include<bits/stdc++.h>
    #define LL long long
    #define db double
    #define il inline
    #define re register
    
    using namespace std;
    const int N=1e5+10;
    il int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    struct node
    {
        int l,r,d,x;
        bool operator < (const node &bb) const {return x!=bb.x?x<bb.x:d<bb.d;}
    }a[N<<1];
    il bool cmp(node a,node b){return a.l<b.l;}
    int n,m,kk;
    LL f[N][210],inf=1ll<<50;
    priority_queue<node> q;
    
    int main()
    {
        //wtcl
        n=rd(),m=rd(),kk=rd();
        for(int i=1;i<=kk;++i) a[i].l=rd(),a[i].r=rd(),a[i].d=rd(),a[i].x=rd();
        for(int i=1;i<=n;++i) ++kk,a[kk].l=a[kk].r=a[kk].d=i,a[kk].x=0;
        sort(a+1,a+kk+1,cmp);
        memset(f,0x3f3f3f,sizeof(f));
        f[0][0]=0;
        for(int i=1,o=1;i<=n;++i)
        {
            while(a[o].l==i) q.push(a[o++]);
            while(!q.empty()&&q.top().r<i) q.pop();
            int d=n+1,x=inf;
            if(!q.empty()) d=q.top().d,x=q.top().x;
            for(int j=0;j<=m;++j)
            {
                f[i][j+1]=min(f[i][j+1],f[i-1][j]);
                f[d][j]=min(f[d][j],f[i-1][j]+x);
            }
        }
        LL ans=inf;
        for(int j=0;j<=m;++j) ans=min(ans,f[n][j]);
        cout<<ans<<endl;
        return 0;
    }
    

    F

    题意

    一个数列,(f_1=f_2=...=f_{k-1}=1,f_n=m),并且(f_i=prod_{j=1}^{k}{f_{i-j}}^{b_j}),问(f_k)

    题解

    首先通过手玩可以发现式子可以转化成({f_k}^a=f_n=m),然后这个k是可以矩乘求出的(怎么求自己玩去).注意到模数为998244353,原根为3,可以考虑原根,即设(f_k=g^x,m=g^y),原式变为(g^{ax}=g^y(mod 998244353)),根据欧拉定理,这等价于(ax=y(mod 998244352)),然后y可以bsgs求,x可以exgcd求

    注意欧拉定理,矩乘模数是原模数-1

    我这种菜鸡什么板子都写错,pp都pp不了

    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    
    using namespace std;
    const int N=700+10,mod=998244353,g=3;
    il LL rd()
    {
        LL x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    map<int,int> ha;
    il LL fpow(LL a,LL b){LL an=1;while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;}return an;}
    il LL bsgs(LL a,LL b)
    {
        ha.clear();
        LL kk=sqrt(mod)+1,aa=b,ka=fpow(a,kk);
        for(int i=0;i<kk;++i) ha[aa]=i,aa=aa*a%mod;
        aa=1;
        for(int i=0;i<=kk;++i)
        {
            if(ha.find(aa)!=ha.end()&&i*kk-ha[aa]>=0) return i*kk-ha[aa];
            aa=aa*ka%mod;
        }
        return -1;
    }
    int n,m,kk,b[110];
    struct martix
    {
      int n,m;
      int a[110][110];
      martix(){}
      il void init()
      {
        for(int i=1;i<=n;i++) a[i][i]=1;
      }
      martix(int n,int m):n(n),m(m)
      {
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
             a[i][j]=0;
      }
      martix operator * (const martix &b) const
      {
        martix an(n,b.m);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
        for(int k=1;k<=b.m;k++)
          an.a[i][j]=(an.a[i][j]+1ll*a[i][k]*b.a[k][j]%(mod-1))%(mod-1);
        return an;
      }
      martix operator ^ (const LL &bb) const
      {
        martix a=*this,an(a.n,a.m);
        an.init();
        LL b=bb;
        while(b)
          {
       		 if(b&1) an=an*a;
       		 a=a*a,b>>=1;
          }
        return an;
      }
    }ma,mb;
    il void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
    {
        if(!b){d=a,x=1,y=0;return;}
        exgcd(b,a%b,d,y,x),y-=a/b*x;
    }
    
    int main()
    {
        n=rd();
        for(int i=1;i<=n;++i) b[i]=rd();
        kk=rd(),m=rd();
        ma.n=ma.m=mb.n=mb.m=n;
        ma.a[1][n]=1;
        for(int i=1;i<n;++i) mb.a[i+1][i]=1;
        for(int i=1;i<=n;++i) mb.a[n-i+1][n]=b[i]%(mod-1);
        ma=ma*(mb^(kk-n));
        LL bb=bsgs(g,m),x,y,d;
        //cout<<ma.a[1][n]<<endl;sgllsjlg
        //cout<<bb<<endl;
        if(bb==-1) return puts("-1"),0;
        exgcd(ma.a[1][n],mod-1,d,x,y);
        //cout<<d<<endl;
        if(bb%d) return puts("-1"),0;
        y=(mod-1)/d;
        //cout<<x<<endl;
        x=(1ll*(x%y+y)%y*(bb/d)%y+y)%y;
        printf("%d
    ",(int)fpow(g,x));
        return 0;
    }
    
  • 相关阅读:
    PHP7.X 安装mysql扩展
    雷军说云计算是下一个风口
    玩转超级列表框4 拖放组建的使用。
    玩转超级列表框第三课的自编代码
    易语言核心支持库 文本操作与文件读写
    插入表项的标题和置标题的标题的区别
    精易模块8.2 类_超级列表框 外部超级列表框的区别和使用注意点
    如何理解动态规划
    雷军:互联网思维本质上就是群众路线
    纯互联网项目“失宠”乐博资本杨宁称今后只投O2O
  • 原文地址:https://www.cnblogs.com/smyjr/p/10358029.html
Copyright © 2020-2023  润新知