zoukankan      html  css  js  c++  java
  • [考试反思]0910csp-s模拟测试42:追求

    显而易见的暴力骗分。

    T1想到了bitset但是发现MLE后弃了,部分分都没拿。

    T2想到正解贪心打暴力过不了大样例弃了。

    T3牛逼题暴力。

    考场没什么大失误,还可以。

    不要轻易放弃每一个思路,可能再优化一下就是正解。不要知足于暴力。

    T1:世界线

    经典问题:求DAG中每一个点能到达多少点。

    很容易想到bitset,但是这题卡空间让人愣了一下。

    其实很简单,分两次跑,第一次处理出每一个点能到前30000号点里的哪些点。

    第二次同理处理后30000个点。这样内存就减半了。

    时间复杂度不变。O(n2/32)

     1 #include<cstdio>
     2 #include<bitset>
     3 using namespace std;
     4 bitset<30002>b[60001];long long ans;
     5 int n,m,fir[60005],l[100005],to[100005],cnt,a,bs,in[100005],q[60005],qt,in2[60005];
     6 void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;in[b]++;}
     7 int main(){
     8     scanf("%d%d",&n,&m);ans=-m;
     9     for(int i=1;i<=m;++i)scanf("%d%d",&a,&bs),link(bs,a);
    10     for(int i=1;i<=n&&i<=30000;++i)b[i][i]=1;
    11     for(int i=1;i<=n;++i)in2[i]=in[i];
    12     for(int i=1;i<=n;++i)if(!in[i])q[++qt]=i;
    13     for(int qh=1;qh<=qt;++qh)for(int j=fir[q[qh]];j;j=l[j]){
    14         b[to[j]]|=b[q[qh]];
    15         in[to[j]]--;
    16         if(!in[to[j]])q[++qt]=to[j];
    17     }
    18     for(int i=1;i<=n;++i)ans+=b[i].count(),b[i].reset();
    19     for(int i=30001;i<=n;++i)b[i][i-30000]=1;
    20     qt=0;
    21     for(int i=1;i<=n;++i)if(!in2[i])q[++qt]=i;
    22     for(int qh=1;qh<=qt;++qh)for(int j=fir[q[qh]];j;j=l[j]){
    23         b[to[j]]|=b[q[qh]];
    24         in2[to[j]]--;
    25         if(!in2[to[j]])q[++qt]=to[j];
    26     }
    27     for(int i=1;i<=n;++i)ans+=b[i].count();
    28     printf("%lld
    ",ans-n);
    29 }
    View Code

    思路积累:

    • bitset求所有能互相到达的点对。
    • 分多次跑节约空间。
    • bitset常数很小。

    T2:时间机器

    直接贪心。

    运用单调性,把供给与需求的左端点排序,然后对于每一个需求找最小的能覆盖它的右端点。

    最优性/贪心正确性比较显然。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<set>
     4 using namespace std;
     5 struct ps{
     6     int opt,l,r,num,ord;
     7     friend bool operator<(ps a,ps b){return a.r<b.r;}
     8 }p[100005];
     9 bool com(ps a,ps b){return a.l<b.l||(a.l==b.l&&a.opt>b.opt);}
    10 multiset<ps>ss;
    11 int n,m,t,lft[50005];
    12 int main(){//freopen("machine2.in","r",stdin);
    13     scanf("%d",&t);
    14     while(t--){
    15         scanf("%d%d",&n,&m);ss.clear();
    16         for(int i=1;i<=n;++i)scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].num),p[i].ord=p[i].opt=0;
    17         for(int j=1;j<=m;++j)scanf("%d%d%d",&p[n+j].l,&p[n+j].r,&p[n+j].num),
    18             lft[j]=p[n+j].num,p[n+j].ord=j,p[n+j].opt=1;
    19         sort(p+1,p+1+n+m,com);//for(int i=1;i<=n+m;++i)printf("%d %d
    ",p[i].l,p[i].opt);
    20         for(int i=1;i<=n+m;++i)
    21             if(p[i].opt)ss.insert(p[i]);//,puts("+");
    22         else while(p[i].num){//puts("-");printf("%d
    ",ss.size());printf("%d -> ",p[i].num);
    23                 if(ss.lower_bound((ps){0,0,p[i].r,0,0})==ss.end())goto fal;
    24                 ps gt=*ss.lower_bound((ps){0,0,p[i].r,0,0});
    25                 int Num=lft[gt.ord];
    26                 if(Num>p[i].num)lft[gt.ord]-=p[i].num,p[i].num=0;
    27                 else p[i].num-=Num,ss.erase(ss.lower_bound((ps){0,0,p[i].r,0,0}));//printf("%d
    ",p[i].num);
    28             }
    29         puts("Yes");continue;
    30         fal:puts("No");
    31     }
    32 }
    View Code

    思路积累:

    • 二位限制的贪心可以先排序一维再做。(CDQ)
    • 把需求和供给等不同操作放在一起排序后处理。(CDQ,莫队思想)

    T3:密码

    神仙题。跟题解。

    求$sumlimits_{i=1}^{n} sumlimits_{j=0}^{i} [C_i^j mod  p^k==0] $

    组合数可以表示为阶乘形式,设$f[i]$表示i的阶乘分解质因数后因子p的个数。

    那么问题转化为$sumlimits_{i=1}^{n} sumlimits_{j=0}^{i} [f[i]-f[j]-f[i-j]>k]$

    对于n的阶乘,其含有的因子p个数为$sum n/p_i$

    组合数$C_n^m$也就可以转化为$sum (n/p^i + m/p^i + (n-m)/p^i) $

    $sum$后面的项的值只可能是0或1,那么考虑其含义:p进制下两数相加不超过n而加法过程当中的进位次数

    问题就是p进制下两数相加不超过n而加法过程当中的进位次数大于等于k的方案数

    p进制数位dp。dp[i][j][k][l]表示考虑到第i位,已进位j次,是否受限制,这一位是否需要进位(后两维大小为1)

    枚举p进制下每一位中[0,p)的取值,复杂度$O(log_p^n imes p^2)$

    但是其实很多枚举所进入的下一层状态是完全相同的,不用枚举,所有方案数都是等差数列之和。根据含义推即可。

    至于进制转化,while高精下模一下除一下即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 #define mod 100000000
     6 #define Mod 1000000007
     7 #define L lim[al]
     8 int lim[3333],l,p,k,pw[10];char N[1005];
     9 int dp[3333][3333][2][2];
    10 #define DP dp[al][up][islim][nup]
    11 struct Int{
    12     long long a[128],ws;
    13     friend int operator%(Int &a,int b){
    14         for(int i=a.ws-1;i;--i)a.a[i-1]+=a.a[i]%b*mod,a.a[i]/=b;
    15         int res=a.a[0]%b;a.a[0]/=b;
    16         while(a.ws&&!a.a[a.ws-1])a.ws--;
    17         return res;
    18     }
    19 }n;
    20 long long sch(int al,int up,int islim,int nup){
    21     if(~DP)return DP;
    22     if(al==l+1)return DP=(up>=k&&!nup);
    23     if(nup){
    24         if(!islim)return DP=(sch(al+1,up,0,0)*((p-1ll)*p/2%Mod)+sch(al+1,up+1,0,1)*((p+1ll)*p/2%Mod))%Mod;
    25         else return DP=(sch(al+1,up,0,0)*((2*p-1ll-L)*L/2%Mod)+sch(al+1,up+1,0,1)*((2*p-L+1ll)*L/2%Mod)
    26              +sch(al+1,up,1,0)*(p-L-1)+sch(al+1,up+1,1,1)*(p-L))%Mod;
    27     }else{
    28         if(!islim)return DP=(sch(al+1,up,0,0)*((1ll+p)*p/2%Mod)+sch(al+1,up+1,0,1)*((p-1ll)*p/2%Mod))%Mod;
    29         else return DP=(sch(al+1,up,0,0)*((L+1ll)*L/2%Mod)+sch(al+1,up+1,0,1)*((L-1ll)*L/2%Mod)
    30              +sch(al+1,up,1,0)*(L+1)+sch(al+1,up+1,1,1)*L)%Mod;
    31     }
    32 }
    33 int main(){//freopen("password9.in","r",stdin);
    34     pw[0]=1;for(int i=1;i<=7;++i)pw[i]=pw[i-1]*10;
    35     scanf("%s%d%d",N,&p,&k);
    36     while(N[l])l++;reverse(N,N+l);
    37     for(int com=0;com<l;++com) n.a[com/8]+=(N[com]-48)*pw[com%8];
    38     n.ws=(l-1)/8+1;l=0;
    39     while(n.ws)lim[++l]=n%p;
    40     reverse(lim+1,lim+l+1);
    41     if(k>l){puts("0");return 0;}
    42     memset(dp,0xff,sizeof dp);
    43     printf("%lld
    ",sch(1,0,1,0));
    44 }
    View Code
  • 相关阅读:
    uva11572 Unique Snowflakes
    codeforces#333 div2 B. Approximating a Constant Range
    uva11134 Fabled Rooks
    吐槽。。。
    uva 1605 Building for UN
    uva 120 Stacks of Flapjacks
    uva1152 4 Values whose Sum is 0
    uva817 According to Bartjens
    uva11214 Guarding the Chessboard
    无标题
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11523671.html
Copyright © 2011-2022 走看看