• 北京集训:20180316


    吃了某种抑制神经的药的蒟蒻真是药丸......
    别问我为什么推到今天才补,才不告诉你我拖延症犯了......

    T1:


    一看就是不可做的构造题......
    前20分爆搜,后20分估计是什么状压,然而并不会写......
    考虑f[i][j][k][l]表示礼物i在j,k在l是否可行,
    我们可以通过一个类似于点分治的dfs预处理出这些信息。
    如果我们把每个礼物在某个节点看做新图上一个点的话,我们就要在新图上找一个大小为n的团......
    最大团什么的,不是NP问题吗?这玩意人干事?
    算了,写个爆搜搞搞就好......
    成绩出来发现跑过了4个点,第一个点WA了woc......
    正解是2-sat。
    考虑f[i][j][0/1]表示礼物i是否在点j的的子树中。
    那么对于礼物x,y经过点pos,我们需要:
    f[son][x]&f[son][y] = 0
    f[pos][x]|f[pos][y] = 1
    f[son][x]&f[son2][x] = 0
    f[pos][x] -> f[fa][x]。
    然后2-sat建图按照tarjan求出强连通的顺序输出方案即可。
    然而写挂了还是30分......
    考场30分暴力:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<bitset>
     7 using namespace std;
     8 const int maxn=252;
     9 
    10 int s[maxn],t[maxn<<1],nxt[maxn<<1];
    11 bitset<maxn> can[maxn][maxn][maxn],now[maxn][maxn];
    12 bitset<maxn> sons[maxn],full;
    13 vector<pair<int,int> > vs[maxn];
    14 bool bad[maxn][maxn];
    15 int fm[maxn],ans[maxn];
    16 int n,m,q;
    17 
    18 inline void addedge(int from,int to) {
    19     static int cnt = 0;
    20     t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
    21 }
    22 inline void dfs(int pos,int fa,int bel) {
    23     sons[bel][pos] = 1 , fm[pos] = bel;
    24     for(int at=s[pos];at;at=nxt[at]) if( t[at] != fa ) dfs(t[at],pos,bel);
    25 }
    26 inline void solvepos(int pos) {
    27     if( !vs[pos].size() ) return;
    28     for(int at=s[pos];at;at=nxt[at]) {
    29         sons[t[at]] &= 0;
    30         dfs(t[at],pos,t[at]);
    31     }
    32     for(unsigned j=0;j<vs[pos].size();j++) {
    33         const int x = vs[pos][j].first , y = vs[pos][j].second;
    34         for(int i=1;i<=n;i++) if( i != pos ) {
    35             can[x][i][y] &= ( full ^ sons[fm[i]] );
    36             can[y][i][x] &= ( full ^ sons[fm[i]] );
    37         }
    38     }
    39 }
    40 inline void cpy(int dst,int sou) {
    41     for(int i=1;i<=m;i++) now[dst][i] = now[sou][i];
    42 }
    43 inline void afs(int pos) {
    44     if( pos == 1 ) {
    45         for(int i=1;i<=m;i++)
    46             for(int j=1;j<=m;j++)
    47                 now[i][j] = full;
    48     }
    49     if( pos > m ) {
    50         for(int i=1;i<=m;i++) printf("%d%c",ans[i],i!=m?' ':'
    ');
    51         exit(0);
    52     }
    53     for(int i=1,fail;i<=n;i++) if( now[pos][pos][i] && !bad[pos][i] ) {
    54         ans[pos] = i , fail = 0;
    55         cpy(pos+1,pos);
    56         for(int j=1;j<=m;j++) {
    57             now[pos+1][j] &= can[pos][i][j];
    58             if( !now[pos+1][j].count() ) {
    59                 fail = 1;
    60                 break;
    61             }
    62         }
    63         if( !fail ) afs(pos+1);
    64     }
    65 }
    66 inline void getbad() {
    67     for(int i=1;i<=m;i++)
    68         for(int j=1;j<=n;j++)
    69             for(int k=1;k<=m;k++)
    70                 if( !can[i][j][k].count() ) {
    71                     bad[i][j] = 1;
    72                     break;
    73                 }
    74 }
    75 int main() {
    76     scanf("%d%d%d",&n,&m,&q);
    77     for(int i=1,a,b;i<n;i++) {
    78         scanf("%d%d",&a,&b);
    79         addedge(a,b) , addedge(b,a);
    80     }
    81     for(int i=1,a,b,t;i<=q;i++) {
    82         scanf("%d%d%d",&a,&b,&t);
    83         vs[t].push_back(make_pair(a,b));
    84     }
    85     for(int i=1;i<=n;i++) full[i] = i;
    86     for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) for(int k=1;k<=m;k++) can[i][j][k] = full;
    87     for(int i=1;i<=n;i++) solvepos(i);
    88     getbad();
    89     afs(1);
    90     return 0;
    91 }
    View Code

    写挂的30分正解:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 #define debug cout
      7 using namespace std;
      8 const int maxn=13000,maxe=6300000,maxl=300;
      9 
     10 int n,m;
     11 int ans[maxl],dep[maxl];
     12 
     13 namespace Tsat {
     14     int s[maxn],t[maxe],nxt[maxe];
     15     int vis[maxn],dfn[maxn],low[maxn],bel[maxn],dd,iid;
     16     int ins[maxn],stk[maxn],top;
     17     inline void addedge(int from,int to) {
     18         static int cnt = 0;
     19         t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
     20     }
     21     inline int cov(int pri,int pos,int sta) { // sta == 0 means not , sta == 1 means yes .
     22         return m * 2 * ( pri - 1 ) + ( pos - 1 ) * 2 + 1 + sta;
     23     }
     24     inline void dfs(int pos) {
     25         vis[pos] = 1;
     26         stk[++top] = pos , ins[pos] = 1;
     27         low[pos] = dfn[pos] = ++dd;
     28         for(int at=s[pos];at;at=nxt[at])
     29             if( !vis[t[at]] ) {
     30                 dfs(t[at]);
     31                 low[pos] = min( low[pos] , low[t[at]] );
     32             } else if( ins[t[at]] ) low[pos] = min( low[pos] , dfn[t[at]] );
     33         if( low[pos] == dfn[pos] ) {
     34             ++iid;
     35             do {
     36                 const int x = stk[top--];
     37                 bel[x] = iid , ins[x] = 0;
     38             } while( ins[pos] );
     39         }
     40     }
     41     inline void findway() {
     42         for(int i=1;i<=m;i++) ans[i] = 1;
     43         for(int i=1;i<=m;i++)
     44             for(int j=1;j<=n;j++) {
     45                 const int c0 = cov(i,j,0) , c1 = cov(i,j,1);
     46                 if( bel[c1] < bel[c0] && dep[ans[i]] < dep[j] ) ans[i] = j;
     47             }
     48     }
     49     inline void work() {
     50         for(int i=1;i<=n*m*2;i++) if( !vis[i] ) dfs(i);
     51         findway();
     52     }
     53 }
     54 
     55 namespace Tree {
     56     int s[maxl],t[maxl<<1],nxt[maxl<<1];
     57     vector<pair<int,int> > vec[maxl];
     58     inline void addedge(int from,int to) {
     59         static int cnt = 0;
     60         t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
     61     }
     62     inline void dfs(int pos,int fa) {
     63         vector<int> sons;
     64         for(int at=s[pos];at;at=nxt[at]) if( t[at] != fa ) {
     65             sons.push_back(t[at]);
     66             dep[t[at]] = dep[pos] + 1 , dfs(t[at],pos);
     67         }
     68         #define cov(x,y,z) Tsat::cov(x,y,z)
     69         #define _addedge(a,b) Tsat::addedge(a,b)
     70         for(unsigned i=0;i<vec[pos].size();i++) {
     71             const int x = vec[pos][i].first , y = vec[pos][i].second;
     72             for(unsigned j=0;j<sons.size();j++) {
     73                 const int c = sons[j];
     74                 _addedge(cov(x,c,1),cov(y,c,0)) ,
     75                 _addedge(cov(y,c,1),cov(x,c,0)) ;
     76             }
     77             _addedge(cov(x,pos,0),cov(y,pos,1)) ,
     78             _addedge(cov(y,pos,0),cov(x,pos,1)) ;
     79         }
     80         if( ~fa ) for(int k=1;k<=m;k++) _addedge(cov(k,pos,1),cov(k,fa,1));
     81         for(unsigned i=0;i<sons.size();i++)
     82             for(unsigned j=i+1;j<sons.size();j++)
     83                 for(int k=1;k<=m;k++) {
     84                     const int x = sons[i] , y = sons[j];
     85                     _addedge(cov(k,x,1),cov(k,y,0)) ,
     86                     _addedge(cov(k,y,1),cov(k,x,0)) ;
     87                 }
     88     }
     89 }
     90 
     91 int main() {
     92     static int q;
     93     scanf("%d%d%d",&n,&m,&q);
     94     for(int i=1,a,b;i<n;i++) {
     95         using Tree::addedge;
     96         scanf("%d%d",&a,&b) , addedge(a,b) , addedge(b,a);
     97     }
     98     for(int i=1,a,b,c;i<=q;i++) {
     99         using Tree::vec;
    100         scanf("%d%d%d",&a,&b,&c) , vec[c].push_back(make_pair(a,b));
    101     }
    102     dep[1] = 1;
    103     Tree::dfs(1,-1);
    104     Tsat::work();
    105     for(int i=1;i<=m;i++) printf("%d%c",ans[i],i!=m?' ':'
    ');
    106     return 0;
    107 }
    108 
    109 /*
    110 5 5 5
    111 1 2
    112 1 3
    113 3 4
    114 2 5
    115 1 1 2
    116 2 4 2
    117 5 4 2
    118 2 4 5
    119 1 4 1
    120 
    121 2 5 1 1 2
    122 */
    View Code

    Commit @ 2018.03.19
    这个2sat终于调对了......
    其实我们还需要加一条边:!f[fa][x] -> !f[pos][x]。
    然后就是数组又开小了,250*250是1.3e5级别的,我开了1.3e4......
    真·蒟蒻不识数
    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<vector>
      6 #define debug cout
      7 using namespace std;
      8 const int maxn=130000,maxe=6300000,maxl=300;
      9 
     10 int n,m;
     11 int ans[maxl],dep[maxl];
     12 
     13 vector<pair<int,int> > es;
     14 namespace Tsat {
     15     int s[maxn],t[maxe],nxt[maxe];
     16     int vis[maxn],dfn[maxn],low[maxn],bel[maxn],dd,iid;
     17     int ins[maxn],stk[maxn],top;
     18     inline void addedge(int from,int to) {
     19         static int cnt = 0;
     20         t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
     21         es.push_back(make_pair(from,to));
     22     }
     23     inline int cov(int pri,int pos,int sta) { // sta == 0 means not , sta == 1 means yes .
     24         return m * 2 * ( pri - 1 ) + ( pos - 1 ) * 2 + 1 + sta;
     25     }
     26     inline void dfs(int pos) {
     27         vis[pos] = 1;
     28         stk[++top] = pos , ins[pos] = 1;
     29         low[pos] = dfn[pos] = ++dd;
     30         for(int at=s[pos];at;at=nxt[at])
     31             if( !vis[t[at]] ) {
     32                 dfs(t[at]);
     33                 low[pos] = min( low[pos] , low[t[at]] );
     34             } else if( ins[t[at]] ) low[pos] = min( low[pos] , dfn[t[at]] );
     35         if( low[pos] == dfn[pos] ) {
     36             ++iid;
     37             do {
     38                 const int x = stk[top--];
     39                 bel[x] = iid , ins[x] = 0;
     40             } while( ins[pos] );
     41         }
     42     }
     43     inline void findway() {
     44         for(int i=1;i<=m;i++) ans[i] = 1;
     45         for(int i=1;i<=m;i++)
     46             for(int j=1;j<=n;j++) {
     47                 const int c0 = cov(i,j,0) , c1 = cov(i,j,1);
     48                 if( bel[c1] < bel[c0] && dep[ans[i]] < dep[j] ) ans[i] = j;
     49             }
     50     }
     51     inline void work() {
     52         for(int i=1;i<=n*m*2;i++) if( !vis[i] ) dfs(i);
     53         findway();
     54     }
     55 }
     56 
     57 namespace Tree {
     58     int s[maxl],t[maxl<<1],nxt[maxl<<1];
     59     vector<pair<int,int> > vec[maxl];
     60     vector<int> sons[maxl];
     61     inline void addedge(int from,int to) {
     62         static int cnt = 0;
     63         t[++cnt] = to , nxt[cnt] = s[from] , s[from] = cnt;
     64     }
     65     inline void dfs(int pos,int fa) {
     66         for(int at=s[pos];at;at=nxt[at]) if( t[at] != fa ) {
     67             sons[pos].push_back(t[at]);
     68             dep[t[at]] = dep[pos] + 1 , dfs(t[at],pos);
     69         }
     70         #define cov(x,y,z) Tsat::cov(x,y,z)
     71         #define _addedge(a,b) Tsat::addedge(a,b)
     72         for(unsigned i=0;i<vec[pos].size();i++) {
     73             const int x = vec[pos][i].first , y = vec[pos][i].second;
     74             for(unsigned j=0;j<sons[pos].size();j++) {
     75                 const int c = sons[pos][j];
     76                 _addedge(cov(x,c,1),cov(y,c,0)) ,
     77                 _addedge(cov(y,c,1),cov(x,c,0)) ;
     78             }
     79             _addedge(cov(x,pos,0),cov(y,pos,1)) , 
     80             _addedge(cov(y,pos,0),cov(x,pos,1)) ;
     81         }
     82         if( ~fa ) for(int k=1;k<=m;k++) {
     83             _addedge(cov(k,pos,1),cov(k,fa,1));
     84             _addedge(cov(k,fa,0),cov(k,pos,0)); // !
     85         }
     86         for(unsigned i=0;i<sons[pos].size();i++)
     87             for(unsigned j=i+1;j<sons[pos].size();j++)
     88                 for(int k=1;k<=m;k++) {
     89                     const int x = sons[pos][i] , y = sons[pos][j];
     90                     _addedge(cov(k,x,1),cov(k,y,0)) ,
     91                     _addedge(cov(k,y,1),cov(k,x,0)) ;
     92                 }
     93     }
     94 }
     95 
     96 int main() {
     97     static int q;
     98     scanf("%d%d%d",&n,&m,&q);
     99     for(int i=1,a,b;i<n;i++) {
    100         using Tree::addedge;
    101         scanf("%d%d",&a,&b) , addedge(a,b) , addedge(b,a);
    102     }
    103     for(int i=1,a,b,c;i<=q;i++) {
    104         using Tree::vec;
    105         scanf("%d%d%d",&a,&b,&c) , vec[c].push_back(make_pair(a,b));
    106     }
    107     dep[1] = 1;
    108     Tree::dfs(1,-1);
    109     Tsat::work();
    110     sort(es.begin(),es.end());
    111     for(int i=1;i<=m;i++) printf("%d%c",ans[i],i!=m?' ':'
    ');
    112     return 0;
    113 }
    View Code


    T2:


    显然有一个非常好写的k^2插值。
    然而我连拉格朗日插值都不会......
    写了个多项式取模乱搞,卡成O(k^3)一分没有......
    只有第一个点的10分。
    其实拉格朗日插值不用求出多项式的,只要把你需要求值的x带进去即可。
    正解为下面的一堆......


    求出g然后用g插n即可。
    拉格朗日插值的作用大概就是是用小范围的信息计算大范围的信息。
    考场10分代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #define debug cout
      7 typedef long long int lli;
      8 using namespace std;
      9 const int maxn=4e3+1e2;
     10 const int mod=1e9+7;
     11 
     12 lli inv[maxn];
     13 int in[maxn];
     14 int k;
     15 
     16 inline lli fastpow(lli base,int tim) {
     17     lli ret = 1;
     18     while( tim ) {
     19         if( tim & 1 ) ret = ret * base % mod;
     20         if( tim >>= 1 ) base = base * base % mod;
     21     }
     22     return ret;
     23 }
     24 
     25 struct Poly {
     26     lli dat[maxn];
     27     Poly(int aa=0,int bb=0) {
     28         memset(dat,0,sizeof(dat));
     29         dat[1] = ( aa % mod + mod ) % mod , dat[0] = ( bb % mod + mod ) % mod;
     30     }
     31     lli& operator [] (const int &x) {
     32         return dat[x];
     33     }
     34     const lli& operator [] (const int &x) const {
     35         return dat[x];
     36     }
     37     friend Poly operator * (const Poly &a,const Poly &b) {
     38         Poly ret;
     39         for(int i=0;i<k+2;i++) for(int j=0;j<k+2;j++) ( ret[i+j] += a[i] * b[j] % mod ) %= mod;
     40         return ret;
     41     }
     42     friend Poly operator / (const Poly &a,const Poly &b) {
     43         Poly ret,tp=a;
     44         int hgh = k+2;
     45         while( !b[hgh] ) --hgh;
     46         for(int i=(k+2)<<1;i>=hgh;i--) if( tp[i] ) {
     47             const lli mul = tp[i] * fastpow(b[hgh],mod-2);
     48             ret[i-hgh] = mul;
     49             for(int t=0;t<=hgh;t++) ( ( tp[i-t] -= b[hgh-t] * mul % mod ) += mod ) %= mod;
     50         }
     51         return ret;
     52     }
     53     friend Poly operator + (const Poly &a,const Poly &b) {
     54         Poly ret;
     55         for(int i=0;i<k+2;i++)
     56             ret[i] = ( a[i] + b[i] ) % mod;
     57         return ret;
     58     }
     59     friend Poly operator * (const Poly &a,const lli &t) {
     60         Poly ret;
     61         for(int i=0;i<k+2;i++) ret[i] = a[i] * t % mod;
     62         return ret;
     63     }
     64     inline lli calc(lli base) {
     65         lli ret = 0 , now = 1;
     66         for(int i=0;i<k;i++) {
     67             ( ret += now * dat[i] % mod ) %= mod ,
     68             now = now * base % mod;
     69         }
     70         return ret;
     71     }
     72 }pol;
     73 
     74 inline Poly getval() {
     75     Poly ret,pi(0,1),now;
     76     for(int i=0;i<k;i++) pi = pi * Poly(1,-i);
     77     for(int i=0;i<k;i++) {
     78         lli mul = in[i];
     79         for(int j=0;j<k;j++) if( i != j ) {
     80             mul = mul * inv[abs(i-j)] % mod;
     81             if( i - j < 0 ) mul = mod - mul;
     82         }
     83         now = pi / Poly(1,-i);
     84         ret = ret + now * mul;
     85     }
     86     return ret;
     87 }
     88 
     89 inline void getinv() {
     90     static lli fac[maxn];
     91     *fac = 1;
     92     for(int i=1;i<=k;i++) fac[i] = fac[i-1] * i % mod;
     93     inv[k] = fastpow(fac[k],mod-2);
     94     for(int i=k;i;i--) inv[i-1] = inv[i] * i % mod;
     95     for(int i=1;i<=k;i++) inv[i] = inv[i] * fac[i-1] % mod;
     96 }
     97 
     98 int main() {
     99     static int n,q;
    100     static lli ans;
    101     scanf("%d%d%d",&n,&k,&q) , ++k;
    102     for(int i=0;i<k;i++) scanf("%d",in+i);
    103     if( n < k ) {
    104         for(int i=0;i<=n;i++) ans = ( ans + in[i] * fastpow(q,i) % mod ) % mod;
    105         return printf("%lld
    ",ans),0;
    106     }
    107     getinv();
    108     pol = getval();
    109     for(int i=0;i<=n;i++) ans = ( ans + pol.calc(i) * fastpow(q,i) % mod ) % mod;
    110     printf("%lld
    ",ans);
    111     return 0;
    112 }
    View Code

    修正40分暴力:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #define debug cout
      7 typedef long long int lli;
      8 using namespace std;
      9 const int maxn=5e5+1e2;
     10 const int mod=1e9+7;
     11 
     12 struct Node {
     13     lli a,b;
     14     friend Node operator + (const Node &a,const Node &b) {
     15         return (Node){(a.a+b.a)%mod,(a.b+b.b)%mod};
     16     }
     17     friend Node operator * (const Node &a,const lli &x) {
     18         return (Node){a.a*x%mod,a.b*x%mod};
     19     }
     20     friend Node operator + (const Node &a,const lli &x) {
     21         return (Node){a.a,(a.b+x)%mod};
     22     }
     23 }ns[maxn];
     24 
     25 lli in[maxn],g[maxn],fac[maxn],inv[maxn];
     26 int k,p;
     27 
     28 inline lli fastpow(lli base,int tim) {
     29     lli ret = 1;
     30     while(tim) {
     31         if( tim & 1 ) ret = ret * base % mod;
     32         if( tim >>= 1 ) base = base * base % mod;
     33     }
     34     return ret;
     35 }
     36 
     37 inline void pre() {
     38     *fac = 1;
     39     for(int i=1;i<=k;i++) fac[i] = fac[i-1] * i % mod;
     40     inv[k] = fastpow(fac[k],mod-2);
     41     for(int i=k;i;i--) inv[i-1] = inv[i] * i % mod;
     42 }
     43 inline lli c(int n,int m) {
     44     return fac[n] * inv[m] % mod * inv[n-m] % mod;
     45 }
     46 
     47 namespace Inter {
     48     lli fac[maxn],facrev[maxn],pprv[maxn],ssuf[maxn],*prv=pprv+1,*suf=ssuf+1;
     49     inline lli getmul(int p) {
     50         return p ? fac[p] * facrev[k-p-1] % mod : facrev[k-1];
     51     }
     52     inline lli getval(lli* in,lli x) {
     53         lli ret = 0;
     54         prv[-1] = 1;
     55         for(int i=0;i<k;i++) prv[i] = prv[i-1] * (x-i+mod) % mod;
     56         suf[k] = 1;
     57         for(int i=k-1;~i;i--) suf[i] = suf[i+1] * (x-i+mod) % mod;
     58         for(int i=0;i<k;i++) {
     59             lli now = prv[i-1] * suf[i+1] % mod;
     60             ret = ret + now * in[i] % mod * getmul(i) % mod , ret %= mod;
     61         }
     62         return ret;
     63     }
     64     inline void getinv() {
     65         static lli inv[maxn];
     66         *fac = 1;
     67         for(int i=1;i<=k;i++) fac[i] = fac[i-1] * i % mod;
     68         inv[k] = fastpow(fac[k],mod-2);
     69         for(int i=k;i;i--)inv[i-1] = inv[i] * i % mod;
     70         for(int i=1;i<=k;i++) inv[i] = inv[i] * fac[i-1] % mod;
     71         for(int i=1;i<=k;i++) fac[i] = fac[i-1] * inv[i] % mod;
     72         facrev[0] = 1;
     73         for(int i=1;i<=k;i++) facrev[i] = facrev[i-1] * ( mod - inv[i] ) % mod;
     74     }
     75 }
     76 
     77 inline void getg0() {
     78     static Node now;
     79     int mul = 1;
     80     for(int i=0;i<=k;i++) {
     81         now = now + ns[k-i] * ( mul == 1 ? c(k,i) : mod - c(k,i) );
     82         mul *= -1;
     83     }
     84     g[0] = ( mod - now.b ) % mod * fastpow(now.a,mod-2) % mod;
     85 }
     86 inline void calc() {
     87     const lli inv = fastpow(p,mod-2);
     88     ns[0] = (Node){1,0};
     89     for(int i=1;i<=k;i++) ns[i] = ( ns[i-1] + in[i-1] ) * inv;
     90     getg0();
     91     for(int i=1;i<=k;i++) g[i] = ( g[i-1] + in[i-1] ) % mod * inv % mod;
     92 }
     93 
     94 int main() {
     95     static lli ans,n;
     96     scanf("%lld%d%d",&n,&k,&p) , ++k;
     97     for(int i=0;i<k;i++) scanf("%lld",in+i);
     98     pre() , calc();
     99     Inter::getinv();
    100     ans = ( Inter::getval(g,n+1) * fastpow(p,(n+1)%(mod-1)) % mod - g[0] + mod ) % mod;
    101     printf("%lld
    ",ans);
    102     return 0;
    103 }
    View Code

    正解代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cstdlib>
      6 #define debug cout
      7 typedef long long int lli;
      8 using namespace std;
      9 const int maxn=5e5+1e2;
     10 const int mod=1e9+7;
     11 
     12 struct Node {
     13     lli a,b;
     14     friend Node operator + (const Node &a,const Node &b) {
     15         return (Node){(a.a+b.a)%mod,(a.b+b.b)%mod};
     16     }
     17     friend Node operator * (const Node &a,const lli &x) {
     18         return (Node){a.a*x%mod,a.b*x%mod};
     19     }
     20     friend Node operator + (const Node &a,const lli &x) {
     21         return (Node){a.a,(a.b+x)%mod};
     22     }
     23 }ns[maxn];
     24 
     25 lli in[maxn],g[maxn],fac[maxn],inv[maxn];
     26 int k,p;
     27 
     28 inline lli fastpow(lli base,int tim) {
     29     lli ret = 1;
     30     while(tim) {
     31         if( tim & 1 ) ret = ret * base % mod;
     32         if( tim >>= 1 ) base = base * base % mod;
     33     }
     34     return ret;
     35 }
     36 inline lli fastpow_lli(lli base,lli tim) {
     37     lli ret = 1;
     38     while(tim) {
     39         if( tim & 1 ) ret = ret * base % mod;
     40         if( tim >>= 1 ) base = base * base % mod;
     41     }
     42     return ret;
     43 }
     44 
     45 inline void pre() {
     46     *fac = 1;
     47     for(int i=1;i<=k;i++) fac[i] = fac[i-1] * i % mod;
     48     inv[k] = fastpow(fac[k],mod-2);
     49     for(int i=k;i;i--) inv[i-1] = inv[i] * i % mod;
     50 }
     51 inline lli c(int n,int m) {
     52     return fac[n] * inv[m] % mod * inv[n-m] % mod;
     53 }
     54 
     55 namespace Inter {
     56     lli fac[maxn],facrev[maxn],pprv[maxn],ssuf[maxn],*prv=pprv+1,*suf=ssuf+1;
     57     inline lli getmul(int p) {
     58         return p ? fac[p] * facrev[k-p-1] % mod : facrev[k-1];
     59     }
     60     inline lli getval(lli* in,lli x) {
     61         x %= mod;
     62         lli ret = 0;
     63         prv[-1] = 1;
     64         for(int i=0;i<k;i++) prv[i] = prv[i-1] * (x-i+mod) % mod;
     65         suf[k] = 1;
     66         for(int i=k-1;~i;i--) suf[i] = suf[i+1] * (x-i+mod) % mod;
     67         for(int i=0;i<k;i++) {
     68             lli now = prv[i-1] * suf[i+1] % mod;
     69             ret = ret + now * in[i] % mod * getmul(i) % mod , ret %= mod;
     70         }
     71         return ret;
     72     }
     73     inline void getinv() {
     74         static lli inv[maxn];
     75         *fac = 1;
     76         for(int i=1;i<=k;i++) fac[i] = fac[i-1] * i % mod;
     77         inv[k] = fastpow(fac[k],mod-2);
     78         for(int i=k;i;i--) inv[i-1] = inv[i] * i % mod;
     79         for(int i=1;i<=k;i++) inv[i] = inv[i] * fac[i-1] % mod;
     80         for(int i=1;i<=k;i++) fac[i] = fac[i-1] * inv[i] % mod;
     81         facrev[0] = 1;
     82         for(int i=1;i<=k;i++) facrev[i] = facrev[i-1] * ( mod - inv[i] ) % mod;
     83     }
     84 }
     85 
     86 inline void getg0() {
     87     static Node now;
     88     int mul = 1;
     89     for(int i=0;i<=k;i++) {
     90         now = now + ns[k-i] * ( mul == 1 ? c(k,i) : mod - c(k,i) );
     91         mul *= -1;
     92     }
     93     g[0] = ( mod - now.b ) % mod * fastpow(now.a,mod-2) % mod;
     94 }
     95 inline void calc() {
     96     const lli inv = fastpow(p,mod-2);
     97     ns[0] = (Node){1,0};
     98     for(int i=1;i<=k;i++) ns[i] = ( ns[i-1] + in[i-1] ) * inv;
     99     getg0();
    100     for(int i=1;i<=k;i++) g[i] = ( g[i-1] + in[i-1] ) % mod * inv % mod;
    101 }
    102 
    103 int main() {
    104     static lli ans,n;
    105     scanf("%lld%d%d",&n,&k,&p) , ++k;
    106     for(int i=0;i<k;i++) scanf("%lld",in+i);
    107     pre() , calc();
    108     Inter::getinv();
    109     ans = ( Inter::getval(g,n+1) * fastpow_lli(p,n+1) % mod - g[0] + mod ) % mod;
    110     printf("%lld
    ",ans);
    111     return 0;
    112 }
    View Code


    T3:


    一个很不靠谱的构造题......
    还有很不靠谱的题解......


    不想改了,把标程丢上来吧......

      1 #include<bits/stdc++.h>
      2 #define lowbit(x) (x&(-x))
      3 #define N 16
      4 using namespace std;
      5 int size[2*N],l[2*N],r[2*N],a[N],n;
      6 double f[2*N][1<<N][N],fac[N];
      7 vector<int> vec[N];
      8 int ls[1<<N],ln,lg[1<<N];
      9 int bitcount(int s){int ans=0;while (s) {ans++;s-=lowbit(s);}return ans;}
     10 void dfs(int s)
     11 {
     12     if (!l[s]) {size[s]=1;return;}
     13     dfs(l[s]);dfs(r[s]);
     14     size[s]=size[l[s]]+size[r[s]];
     15 }
     16 int st[18],top;
     17 void gao(int now,int rem,int w)
     18 {
     19     if (now>top) {ls[++ln]=w;return;}
     20     if (top-now>=rem) gao(now+1,rem,w);
     21     if (rem) gao(now+1,rem-1,w+st[now]);
     22 }
     23 void search(int s,int sz)
     24 {
     25     top=0; 
     26     while (s)
     27     {
     28         st[++top]=lowbit(s);
     29         s-=lowbit(s);
     30     }
     31     gao(1,sz,0);
     32 }
     33 void work(int s)
     34 {
     35     if (!l[s])
     36     {
     37         for (int i=0;i<n;i++) f[s][1<<i][i]=1;
     38         return;
     39     }
     40     work(l[s]);work(r[s]);
     41     double pp=fac[size[l[s]]]*fac[size[r[s]]]/fac[size[s]];
     42     for (int k=0;k<vec[size[s]].size();k++)
     43     {
     44         int d=vec[size[s]][k];
     45         ln=0;search(d,size[l[s]]);
     46         for (int kk=1;kk<=ln;kk++)
     47         {
     48             int dd=ls[kk];
     49             for (int ii=dd,i=lg[lowbit(ii)];ii;ii-=lowbit(ii),i=lg[lowbit(ii)])
     50             for (int jj=d-dd,j=lg[lowbit(jj)];jj;jj-=lowbit(jj),j=lg[lowbit(jj)])
     51             {
     52                 double p=pp*f[l[s]][dd][i]*f[r[s]][d-dd][j]/(a[i]+a[j]);
     53                 f[s][d][i]+=p*a[i];
     54                 f[s][d][j]+=p*a[j];
     55             }
     56         }
     57     }
     58 }
     59 double zuo()
     60 {
     61     memset(f,0,sizeof(f));
     62     memset(size,0,sizeof(size));
     63     dfs(1);work(1);
     64     return f[1][(1<<n)-1][0];
     65 }
     66 int tp;
     67 int gen1(int n)
     68 {
     69     int s=++tp;
     70     if (n==1) {l[s]=r[s]=0;return s;}
     71     int dv=1;
     72     l[s]=gen1(dv);r[s]=gen1(n-dv);
     73     return s;
     74 }
     75 int gen2(int n)
     76 {
     77     int s=++tp;
     78     if (n==1) {l[s]=r[s]=0;return s;}
     79     int dv=n/2;
     80     l[s]=gen2(dv);r[s]=gen2(n-dv);
     81     return s;
     82 }
     83 int gen3(int n)
     84 {
     85     int s=++tp;
     86     if (n==1) {l[s]=r[s]=0;return s;}
     87     int dv=rand()%(n-1)+1;
     88     l[s]=gen3(dv);r[s]=gen3(n-dv);
     89     return s;
     90 }
     91 int main()
     92 {
     93     scanf("%d",&n);
     94     for (int i=0;i<=n;i++) lg[1<<i]=i;
     95     fac[0]=1;for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i;
     96     for (int s=0;s<(1<<n);s++)
     97     {
     98         vec[bitcount(s)].push_back(s);
     99     }
    100     for (int i=0;i<n;i++) scanf("%d",&a[i]);
    101      
    102     int ll=1,rr=100;
    103     while (ll+1!=rr)
    104     {
    105         int mid=(ll+rr)>>1;a[0]=mid;
    106         double p1,p2;
    107         tp=0;gen1(n);p1=zuo();
    108         tp=0;gen2(n);p2=zuo();
    109         if (p1<p2) rr=mid;else ll=mid;
    110     }
    111     a[0]=ll;
    112     double p1,p2,ans;
    113     tp=0;gen1(n);p1=zuo();
    114     tp=0;gen2(n);p2=zuo();
    115     ans=max(p1,p2);
    116     while (1)
    117     {
    118         tp=0;gen3(n);
    119         if (zuo()>ans+1e-9)
    120         {
    121             printf("1
    1 %d
    ",a[0]);
    122             for (int i=1;i<=2*n+1;i++) printf("%d %d
    ",l[i],r[i]);
    123             return 0;
    124         }
    125     }
    126 }
    View Code
  • 相关阅读:
    How to Integrate JCaptcha in Spring Security
    精简的webservice
    linux时间与Windows时间不一致的解决
    java泛型
    spring全局变量引起的并发问题
    ByteBuffer常用方法详解
    cindy
    NIO之Buffer的clear()、rewind()、flip()方法的区别
    Java NIO(New I/O)的三个属性position、limit、capacity
    技术选型
  • 原文地址:https://www.cnblogs.com/Cmd2001/p/8597413.html
Copyright © 2020-2023  润新知