• 20180329小测


    让大家都AK的信心赛......
    话说这种考试有什么意思(不),还不如做我出的那套模拟题呢......

    T1:


    其实这题是我三道题里AC得最晚的......
    首先我们能用bitset+大力背包骗到58-64分......
    考虑我们如果先枚举两个数能组合出的值,再计算另外一个数的方案数,什么情况下会算重?
    显然是当这个值取模最后的那个数相同的时候,这样一个方案数会被计算多次!
    此外还有一个十分显然的结论:当两个值取模最后那个数相同时,较大的那个值的答案会被包含在较小的那个值的答里面。
    这样的话,我们在取模abc中某一个数的同余系下跑一个最短路,用另外两个数做边进行转移,最后再统计一发答案不就好了。
    60分bitset代码:

     1 #pragma GCC optimize(3)
     2 #include<cstdio>
     3 #include<bitset>
     4 const int maxn=1e8+1e2;
     5 std::bitset<maxn> vis;
     6 
     7 long long h;
     8 int a,b,c,ans;
     9 
    10 
    11 int main() {
    12     scanf("%lld%d%d%d",&h,&a,&b,&c);
    13     if( a == 1 || b == 1 || c == 1 ) return printf("%lld
    ",h),0;
    14     for(int i=0;a*i<h;i++) {
    15         if( vis[a*i] ) break;
    16         for(int j=0;a*i+b*j<h;j++) {
    17             if( vis[a*i+b*j] ) break;
    18             for(int k=0;a*i+b*j+k*c<h;k++) {
    19                 if( vis[a*i+b*j+k*c] ) break;
    20                 vis[a*i+b*j+k*c] = 1;
    21             }
    22         }
    23     }
    24     printf("%llu
    ",vis.count());
    25     return 0;
    26 }
    View Code

    正解代码:

     1 #include<bits/stdc++.h>
     2 #define bool unsigned char
     3 typedef long long int lli;
     4 using namespace std;
     5 const int maxn=1e5+1e2;
     6 
     7 lli h,ans;
     8 lli dis[maxn];
     9 int s[maxn],t[maxn<<4],nxt[maxn<<4],l[maxn<<4];
    10 bool inq[maxn];
    11 int a,b,c;
    12 
    13 inline void addedge(int from,int to,int len) {
    14     static int cnt = 0;
    15     t[++cnt] = to , l[cnt] = len ,
    16     nxt[cnt] = s[from] , s[from] = cnt;
    17 }
    18 inline void spfa(int st) {
    19     memset(dis,0x7f,sizeof(dis)) , dis[st] = 0;
    20     queue<int> q; q.push(st) , inq[st] = 1;
    21     while( q.size() ) {
    22         const int pos = q.front(); q.pop() , inq[pos] = 0;
    23         for(int at=s[pos];at;at=nxt[at])
    24             if( dis[t[at]] > dis[pos] + l[at] ) {
    25                 dis[t[at]] = dis[pos] + l[at];
    26                 if( !inq[t[at]] ) q.push(t[at]) , inq[t[at]] = 1;
    27             }
    28     }
    29 }
    30 inline void getans() {
    31     --h;
    32     for(int i=0;i<c;i++)
    33         if( dis[i] <= h )
    34             ans += ( h - dis[i] ) / c + 1;
    35 }
    36 
    37 int main() {
    38     scanf("%lld%d%d%d",&h,&a,&b,&c);
    39     if( a > b ) swap(a,b);
    40     if( b > c ) swap(b,c);
    41     for(int i=0;i<c;i++)
    42         addedge(i,(i+a)%c,a) , addedge(i,(i+b)%c,b);
    43     spfa(0);
    44     getans();
    45     printf("%lld
    ",ans);
    46     return 0;
    47 }
    View Code

    T2:


    怕不是stl:rope裸题......
    rope能实现区间提取,单点插入区间,正好能用来做这道题......
    代码:

     1 #include<iostream>
     2 #include<ext/rope>
     3 const int maxn=2.5e5+1e2;
     4 
     5 char in[maxn];
     6 __gnu_cxx::rope<char> str,ans;
     7 
     8 int main() {
     9     static char com[10];
    10     static int k,len;
    11     std::ios::sync_with_stdio(0) , std::cin.tie(0) , std::cout.tie(0);
    12     std::cin >> in , str = in;
    13     while( ( std::cin >> com ) && *com != 'E' ) {
    14         if( *com == 'I' ) {
    15             std::cin >> in >> k;
    16             str.insert(k,in);
    17         } else if( *com == 'P' ) {
    18             std::cin >> k >> len;
    19             ans = str.substr(k,len-k+1);
    20             std::cout << ans << std::endl;
    21         }
    22     }
    23     return 0;
    24 }
    View Code

    T3:


    如果只是求和应该怎样做?一个很显然的换根树状DP。
    现在要求k次呢?这样的话距离+1-1就需要进行变化了。
    我们维护x^0~x^k的一个多项式,在更新x^k的时候利用二项式定理和更低次的项进行更新就好了。
    这样一次更新复杂度O(k),总复杂度O(nkt),稳稳地AC了。
    根节点深度为1好评,省去了对于0^k等问题的繁琐的分类讨论......
    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define debug cout
      6 typedef long long int lli;
      7 using namespace std;
      8 const int maxn=2e4+1e2,maxk=25;
      9 const int mod=1e9+7;
     10 
     11 
     12 lli c[maxk][maxk];
     13 int n,k;
     14 
     15 namespace Pre {
     16     lli fac[maxk],inv[maxk];
     17     inline lli fastpow(lli base,int tim) {
     18         lli ret = 1;
     19         while( tim ) {
     20             if( tim & 1 ) ret = ret * base % mod;
     21             if( tim >>= 1 ) base = base * base % mod;
     22         }
     23         return ret;
     24     }
     25     inline lli C(int n,int m) {
     26         return fac[n] * inv[m] % mod * inv[n-m] % mod;
     27     }
     28     inline void work() {
     29         *fac = 1;
     30         for(int i=1;i<=k;i++) fac[i] = fac[i-1] * i % mod;
     31         inv[k] = fastpow(fac[k],mod-2);
     32         for(int i=k;i;i--) inv[i-1] = inv[i] * i % mod;
     33         for(int i=0;i<=k;i++)
     34             for(int j=0;j<=i;j++)
     35                 c[i][j] = C(i,j);
     36     }
     37 }
     38 
     39 struct Poly {
     40     lli dat[maxk];
     41     Poly() {
     42         memset(dat,0,sizeof(dat));
     43     }
     44     lli& operator [] (const int &x) {
     45         return dat[x];
     46     }
     47     const lli& operator [] (const int &x) const {
     48         return dat[x];
     49     }
     50     friend Poly operator + (const Poly &a,const Poly &b) {
     51         Poly ret;
     52         for(int i=0;i<=k;i++)
     53             ret[i] = ( a[i] + b[i] ) % mod;
     54         return ret;
     55     }
     56     friend Poly operator - (const Poly &a,const Poly &b) {
     57         Poly ret;
     58         for(int i=0;i<=k;i++)
     59             ret[i] = ( a[i] - b[i] + mod ) % mod;
     60         return ret;
     61     }
     62     friend Poly operator + (const Poly &a,lli x) {
     63         Poly ret; x = ( x + mod ) % mod;
     64         static lli pows[maxk];
     65         *pows = 1;
     66         for(int i=1;i<=k;i++) pows[i] = pows[i-1] * x % mod;
     67         for(int i=k;~i;i--) {
     68             for(int j=i;~j;j--)
     69                 ret[i] += a[j] * pows[i-j] % mod * c[i][j] % mod , ret[i] %= mod;
     70         }
     71         return ret;
     72     }
     73     inline void init() {
     74         for(int i=0;i<=k;i++) dat[i] = 1;
     75     }
     76 }sson[maxn],sfa[maxn],f[maxn];
     77 // sson is dis of points in subtree to pos .
     78 
     79 int s[maxn],t[maxn<<1],nxt[maxn<<1],fa[maxn],cnt;
     80 
     81 inline void addedge(int from,int to) {
     82     t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
     83 }
     84 inline void dfsson(int pos) {
     85     sson[pos].init();
     86     for(int at=s[pos];at;at=nxt[at]) if( t[at] != fa[pos] ) {
     87         fa[t[at]] = pos , dfsson(t[at]);
     88         sson[pos] = sson[pos] + ( sson[t[at]] + 1 ) ;
     89     }
     90 }
     91 inline void dfsfa(int pos) {
     92     if( fa[pos] ) {
     93         sfa[pos] = sfa[fa[pos]] + 1;
     94         Poly delta = sson[fa[pos]] - ( sson[pos] + 1 );
     95         sfa[pos] = sfa[pos] + ( delta + 1 );
     96     }
     97     for(int at=s[pos];at;at=nxt[at]) if( t[at] != fa[pos] ) dfsfa(t[at]);
     98 }
     99 inline void getans() {
    100     for(int i=1;i<=n;i++) {
    101         Poly sum = sfa[i] + sson[i];
    102         printf("%lld
    ",sum.dat[k]);
    103     }
    104     putchar('
    ');
    105 }
    106 
    107 int main() {
    108     while( scanf("%d%d",&n,&k) == 2 ) {
    109         memset(s,0,sizeof(int)*(n+1)) , cnt = 0;
    110         Pre::work();
    111         for(int i=1,a,b;i<n;i++) {
    112             scanf("%d%d",&a,&b) ,
    113             addedge(a,b) , addedge(b,a);
    114         }
    115         dfsson(1) , dfsfa(1);
    116         getans();
    117     }
    118     return 0;
    119 }
    View Code

    最后上排名。
    (为什么3个AK的?因为有一个是我用我老婆的名字注册的账号(四蒸心.jpg))


    话说比赛还没结束呢就发题解真的好吗?
    另外我的桌子竟然带电!准备报警了!

  • 相关阅读:
    bootstrap媒体查询
    Qt用Zip压缩文件夹的一些坑
    QCanvasItem介绍-QT3
    C盘无损扩容
    ArcGis连接oracle失败:ORA-6413:连接未打开
    通过ArcMap发布服务
    windows系统下使用cd命令
    C语言运算符优先级
    c/c++ 指针
    c++数组易错点总结
  • 原文地址:https://www.cnblogs.com/Cmd2001/p/8668694.html
Copyright © 2020-2023  润新知