zoukankan      html  css  js  c++  java
  • 2019.3.16 noiac的原题模拟赛

    RT,这太野蛮了,我不承认这是模拟赛

    但是虽然是搬了三道题,题目本身也还能看,就这么着吧

    (怎么机房里就我一道原题都没做过啊

    T1 CF24D Broken Robot

    比较简单地列出式子之后,我们发现可以自底向上每行做高斯消元求从每个格子出发的期望步数,复杂度$O(n^4)$(边界是最底下一行都是零)

    然后我们发现高斯消元的时候每一行对应的方程就那几个地方有数,于是手动高斯消元一下就可以$O(n^2)$了

     1 #pragma GCC optimize(2)
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=1005,mod=998244353;
     7 int n,m,x,y,inv2,inv3,inv4,in2v,in3v,in4v,in23v,in34v;
     8 int dp[N][N],equ[N][N];
     9 template<class T,class TT> void Mis(TT &x,T y){x-=y; if(x<0) x+=mod;}
    10 template<class T,class TT> int Mi(TT x,T y){x-=y; if(x<0) x+=mod; return x;}
    11 void exGCD(int a,int b,int &x,int &y)
    12 {
    13     if(!b) x=1,y=0;
    14     else exGCD(b,a%b,y,x),y-=a/b*x;
    15 }
    16 int Inv(int x)
    17 {
    18     int xx,yy; 
    19     exGCD(x,mod,xx,yy); 
    20     return (xx%mod+mod)%mod;
    21 }
    22 void Pre()
    23 {
    24     inv2=Inv(2),inv3=Inv(3),inv4=Inv(4);
    25     in2v=mod-inv2,in3v=mod-inv3,in4v=mod-inv4;
    26     in23v=2ll*in3v%mod,in34v=3ll*in4v%mod;
    27 }
    28 void Init(int a)
    29 {
    30     if(m==1) 
    31     {
    32         equ[1][1]=in2v;
    33         equ[1][m+1]=Mi(1ll*dp[a+1][1]*in2v%mod,1);
    34     }
    35     else
    36     {
    37         equ[1][1]=equ[m][m]=in23v;
    38         equ[1][2]=equ[m][m-1]=inv3;
    39         equ[1][m+1]=Mi(1ll*dp[a+1][1]*in3v%mod,1);
    40         equ[m][m+1]=Mi(1ll*dp[a+1][m]*in3v%mod,1);
    41         for(int i=2;i<m;i++)
    42         {
    43             equ[i][i-1]=equ[i][i+1]=inv4,equ[i][i]=in34v;
    44             equ[i][m+1]=Mi(1ll*dp[a+1][i]*in4v%mod,1);
    45         }
    46     }
    47 }
    48 void Guass(int a)
    49 {
    50     register int i;
    51     for(i=1;i<m;i++)
    52     {
    53         int calc=1ll*equ[i+1][i]*Inv(equ[i][i])%mod;
    54         Mis(equ[i+1][i],1ll*calc*equ[i][i]%mod);
    55         Mis(equ[i+1][i+1],1ll*calc*equ[i][i+1]%mod);
    56         Mis(equ[i+1][m+1],1ll*calc*equ[i][m+1]%mod);
    57     }
    58     dp[a][m]=1ll*equ[m][m+1]*Inv(equ[m][m])%mod;
    59     for(i=m-1;i;i--)
    60         dp[a][i]=1ll*Mi(equ[i][m+1],1ll*dp[a][i+1]*equ[i][i+1]%mod)*Inv(equ[i][i])%mod;
    61 }
    62 int main()
    63 {
    64     register int i;
    65     scanf("%d%d%d%d",&n,&m,&x,&y),Pre();
    66     for(i=n-1;i>=x;i--) Init(i),Guass(i);
    67     printf("%d",dp[x][y]);
    68     return 0;
    69 }
    View Code

    T2 CEOI 2017 Building Bridges

    花式优化DP

    沙茶博主->CDQ+sort->$O(nlog^2 n)$

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define lli long long
     5 using namespace std;
     6 const int N=100005;
     7 int n,top,pos[N],stk[N];
     8 lli h[N],s[N],x[N],y[N],dp[N];
     9 void Maxi(lli &x,lli y){if(x<y) x=y;}
    10 void Mini(lli &x,lli y){if(x>y) x=y;}
    11 bool cmp(int a,int b)
    12 {
    13     return x[a]==x[b]?y[a]<y[b]:x[a]<x[b];
    14 }
    15 bool Slope(int a,int b,int c)
    16 {
    17     return (y[a]-y[c])*(x[b]-x[c])>=(y[b]-y[c])*(x[a]-x[c]);
    18 }
    19 lli Calc(int a,int b)
    20 {
    21     return -2*h[b]*x[a]+y[a];
    22 }
    23 void CDQ(int l,int r)
    24 {
    25     if(l==r)
    26         x[l]=h[l],y[l]=dp[l]-s[l]+h[l]*h[l]; 
    27     else
    28     {
    29         int mid=(l+r)>>1;
    30         CDQ(l,mid);
    31         sort(pos+l,pos+1+mid,cmp),top=0;
    32         for(int i=l;i<=mid;i++)
    33         {
    34             while(top>1&&Slope(pos[i],stk[top-1],stk[top])) top--;
    35             stk[++top]=pos[i];
    36         }
    37         for(int i=mid+1;i<=r;i++)
    38         {
    39             int ll=1,rr=top-1,re=top;
    40             while(ll<=rr)
    41             {
    42                 int midd=(ll+rr)>>1;
    43                 if(Calc(stk[midd],i)<Calc(stk[midd+1],i)) re=midd,rr=midd-1;
    44                 else ll=midd+1;
    45             }
    46             Mini(dp[i],Calc(stk[re],i)+s[i-1]+h[i]*h[i]);
    47         }
    48         CDQ(mid+1,r);
    49     }
    50 }
    51 int main()
    52 {
    53     scanf("%d",&n);
    54     for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
    55     for(int i=1;i<=n;i++) scanf("%lld",&s[i]);
    56     for(int i=1;i<=n;i++) pos[i]=i,s[i]+=s[i-1];
    57     memset(dp,0x3f,sizeof dp),dp[1]=0;
    58     CDQ(1,n),printf("%lld",dp[n]);
    59     return 0;
    60 }
    View Code

    T3 UOJ 310 黎明前的巧克力

    拿全集作个差就是一道题了

    我们要选出异或和相同的集合,等价于选出一个异或和为零的集合,然后拆成两个集合。所以可以设计一个朴素的DP:$dp[i][j]$表示考虑前$i$个数选出异或和为$j$的方案数。进一步我们发现这是在FWT,零的贡献是1,当前卷的数对一些位置贡献2,对一些位置贡献-2。又因为FWT是线性变换,所以最终卷出来是一坨1-2=-1和1+2=3。整体做一次FWT之后,解方程得到每个位置具体的-1和3的个数,然后IFWT回来

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define lli long long
     5 using namespace std;
     6 const int N=1100000,mod=998244353;
     7 int n,m,nm,rd,inv2,inv4;
     8 int bkt[N],res[N],fac[N],inv[N];
     9 void Maxi(int &x,int y){if(x<y) x=y;}
    10 int Qpow(int x,int k)
    11 {
    12     if(k==1) return x;
    13     int tmp=Qpow(x,k/2);
    14     return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
    15 }
    16 int C(int a,int b)
    17 {
    18     return 1ll*fac[a]*inv[b]%mod*inv[a-b]%mod;
    19 }
    20 void Pre()
    21 {
    22     int lim=1e6; 
    23     fac[0]=inv[0]=1,nm=1,inv2=Qpow(2,mod-2),inv4=Qpow(4,mod-2);
    24     for(int i=1;i<=lim;i++) fac[i]=1ll*fac[i-1]*i%mod;
    25     inv[lim]=pow(fac[lim],mod-2);
    26     for(int i=lim-1;i;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
    27 }
    28 void Trans(int *arr,int tot,int typ)
    29 {
    30     register int i,j,k; 
    31     for(i=2;i<=tot;i<<=1)    
    32     {
    33         int len=i>>1,tmp;
    34         for(j=0;j<tot;j+=i)
    35             for(k=j;k<j+len;k++)
    36                 tmp=arr[k+len],arr[k+len]=(arr[k]-tmp+mod)%mod,arr[k]=(arr[k]+tmp)%mod;
    37         if(typ==-1)
    38             for(j=0;j<tot;j++)
    39                 arr[j]=1ll*arr[j]*inv2%mod;
    40     }
    41 }
    42 int main()
    43 {
    44     scanf("%d",&n),Pre();
    45     for(int i=1;i<=n;i++)
    46     {
    47         scanf("%d",&rd);
    48         bkt[0]++,bkt[rd]+=2,Maxi(m,rd);
    49     }
    50     while(nm<=m) nm<<=1;
    51     Trans(bkt,nm,1); 
    52     for(int i=0;i<nm;i++)
    53     {
    54         int tmp=1ll*(n+bkt[i])*inv4%mod;
    55         res[i]=((tmp+n)%mod)%2?mod-Qpow(3,tmp):Qpow(3,tmp);
    56     }
    57     Trans(res,nm,-1);
    58     printf("%lld",1ll*(Qpow(3,n)-res[0]+mod)*Qpow(2,mod-2)%mod);
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    折半插入排序-ACM题
    xcode 常用快捷键
    折半插入排序-算法
    插入排序
    HTML5 data-* 自定义属性
    vertical-align属性baseline(转)
    CSS 基础点
    解决-word里无论怎么改变字体颜色,字体总是红色的
    css属性前加*号的作用
    php 函数的嵌套
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10542430.html
Copyright © 2011-2022 走看看