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
  • 相关阅读:
    微人事项目-mybatis-持久层
    通过外键连接多个表
    springioc
    Redis 消息中间件 ServiceStack.Redis 轻量级
    深度数据对接 链接服务器 数据传输
    sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
    sqlserver 索引优化 CPU占用过高 执行分析 服务器检查
    sql server 远程备份 bak 删除
    冒泡排序
    多线程 异步 beginInvoke EndInvoke 使用
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11523671.html
Copyright © 2011-2022 走看看