zoukankan      html  css  js  c++  java
  • 20170125小测

    今天又是例行考试的说。

    话说我今天loj大凶且忌参加模拟赛,洛谷也好不到哪去,怕不是要爆零了QAQ


    T1:卡片游戏:


    这题看到数据范围1e5,铁定不是费用流了。

    这种东西显然不可能是dp,看看怎么贪心?

    首先,我们如果给一张卡片负号,则一定去较大的那个值,正号则取较小的那个。

    两边的差值是大小两值的和。

    所以,我们先贪心地给负号,并把卡片放进一个堆里,如果堆已满且堆顶的数值和小于当前卡片的数值和,那么我们弹出堆顶,放入当前卡片。

    考虑一正一负且负数的绝对值大的情况,也能通过。

    写了拍了没啥问题,就这样了。


    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<set>
     6 #define debug cout
     7 using namespace std;
     8 const int maxn=1e5+1e2;
     9 
    10 struct Node {
    11     int mx,mi;
    12     friend bool operator < (const Node &a,const Node &b) {
    13         return a.mx + a.mi < b.mx + b.mi;
    14     }
    15 }ns[maxn];
    16 
    17 multiset<Node> heap;
    18 
    19 int main() {
    20     static int n,lim,ans;
    21     scanf("%d",&n) , lim = n >> 1;
    22     for(int i=1;i<=n;i++) {
    23         scanf("%d%d",&ns[i].mx,&ns[i].mi);
    24         if( ns[i].mx < ns[i].mi )
    25             swap(ns[i].mx,ns[i].mi);
    26     }
    27     for(int i=1;i<=n;i++) {
    28         if( heap.size() < lim ) {
    29             heap.insert(ns[i]);
    30             ans -= ns[i].mx;
    31         } else if( *heap.begin() < ns[i] ) {
    32             Node b = *heap.begin();
    33             heap.erase(heap.begin());
    34             ans += b.mx , ans += b.mi;
    35             heap.insert(ns[i]);
    36             ans -= ns[i].mx;
    37         } else ans += ns[i].mi;
    38     }
    39     
    40     printf("%d
    ",ans);
    41     
    42     return 0;
    43 }
    View Code


    T2nimgame


    nim游戏?xor?随机方案?不可做不可做,敲了n!暴力走人。

    然后爆零了...…

    正解是NTT,首先第一问如果不是全1则一定为1/2(归纳法易证,有空再补,Fedora输入法反人类!)

    第二问就是奇数次取完的方案数,如果我们算出k次取完每一个的数量,那么答案就是个卷积,指数生成函数启发式NTT即可。


    爆零爆搜代码:

     1 #pragma GCC optimize(3)
     2 #pragma GCC optimize("-funsafe-loop-optimizations")
     3 #pragma GCC optimize("-funroll-loops")
     4 #pragma GCC optimize("-fwhole-program")
     5 #pragma GCC target("mmx")
     6 #include<cstdio>
     7 #define lli long long int
     8 #define debug cout
     9 using namespace std;
    10 const int maxn=1e2+1e1;
    11 const int mod = 2013265921;
    12 
    13 int in[maxn],n;
    14 struct Node {
    15     lli exp;
    16     int way,full;
    17 };
    18 inline lli rev(int base) {
    19     int tme = mod - 2;
    20     lli ret = 1 , now = base;
    21     while( tme ) {
    22         if( tme & 1 ) ret = ret * now % mod;
    23         now = now * now % mod;
    24         tme >>= 1;
    25     }
    26     return ret;
    27 }
    28 
    29 inline bool empty() {
    30     for(int i=1;i<=n;i++)
    31         if( in[i] ) return 0;
    32     return 1;
    33 }
    34 Node dfs() {
    35     if( empty() )
    36         return (Node){0,0,1};
    37     Node ret = (Node){0,0,0};
    38     int ways = 0 , full = 0;
    39     for(int i=1;i<=n;i++)
    40         if( in[i] )
    41             for(int j=1;j<=in[i];j++) {
    42                 in[i] -= j;
    43                 ++ways;
    44                 Node nxt = dfs();
    45                 ret.exp += ( 1 - nxt.exp + mod ) % mod , ret.exp %= mod , ret.way += nxt.way , full += nxt.full;
    46                 in[i] += j;
    47             }
    48     ret.exp = ret.exp * rev(ways) % mod;
    49     ret.way = full - ret.way;
    50     ret.full = full;
    51     return ret;
    52 }
    53 
    54 int main() {
    55     static int T;
    56     scanf("%d",&T);
    57     while( T--) {
    58         scanf("%d",&n);
    59         for(int i=1;i<=n;i++)
    60             scanf("%d",in+i);
    61         Node ans = dfs();
    62         printf("%lld %d
    ",ans.exp,ans.way);
    63     }
    64     return 0;
    65 }
    View Code


    正解代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<functional>
      6 #include<vector>
      7 #include<queue>
      8 #define lli long long int
      9 #define debug cout
     10 using namespace std;
     11 const int maxn=5e4+1e2,maxl=1<<17;
     12 const int mod = 2013265921 , g = 31;
     13 
     14 int len[maxn];
     15 lli fac[maxn],invfac[maxn];
     16 vector<lli> v[maxn];
     17 priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > pq;
     18 
     19 inline lli fastpow(lli base,int tme,int mod) {
     20     lli ret = 1;
     21     while( tme ) {
     22         if( tme & 1 ) ret = ret * base % mod;
     23         base = base * base % mod;
     24         tme >>= 1;
     25     }
     26     return ret;
     27 }
     28 inline lli getinv(lli x) {
     29     return fastpow(x,mod-2,mod);
     30 }
     31 inline lli c(int n,int m) {
     32     return fac[n] * invfac[m] % mod * invfac[n-m] % mod;
     33 }
     34 
     35 inline int revbit(int x,int len) {
     36     int ret = 0;
     37     for(int t=1;t<len;t<<=1)
     38         ret <<= 1 , ret |= x&1 , x >>= 1;
     39     return ret;
     40 }
     41 inline void NTT(lli* dst,int n,int ope) {
     42     for(int i=0,j;i<n;i++) {
     43         j = revbit(i,n);
     44         if( i < j ) swap(dst[i],dst[j]);
     45     }
     46     for(int len=2;len<=n;len<<=1) {
     47         lli per = fastpow( g , mod / len , mod );
     48         if( !~ope ) per = getinv(per);
     49         for(int st=0;st<n;st+=len) {
     50             lli w = 1;
     51             for(int pos=0;pos<len>>1;pos++) {
     52                 const lli x = dst[st+pos] , y = dst[st+pos+(len>>1)] * w % mod;
     53                 dst[st+pos] = ( x + y ) % mod ,
     54                 dst[st+pos+(len>>1)] = ( x - y + mod ) % mod;
     55                 w = w * per % mod;
     56             }
     57         }
     58     }
     59     if( !~ope ) {
     60         lli inv = getinv(n);
     61         for(int i=0;i<n;i++)
     62             dst[i] = dst[i] * inv % mod;
     63     }
     64 }
     65 inline void mul(int x,int y) { // multi v[x] v[y] into v[x] and update len[x]
     66     static lli a[maxl],b[maxl];
     67     int n = 1 , lx = len[x] , ly = len[y];
     68     while( n <= lx + ly ) n <<= 1;
     69     memset(a,0,sizeof(lli)*(n+1)) , memset(b,0,sizeof(lli)*(n+1));
     70     for(int i=0;i<=lx;i++) a[i] = v[x][i];
     71     for(int i=0;i<=ly;i++) b[i] = v[y][i];
     72     NTT(a,n,1) , NTT(b,n,1);
     73     for(int i=0;i<n;i++)
     74         a[i] = a[i] * b[i] % mod;
     75     NTT(a,n,-1);
     76     n = len[x] + len[y];
     77     v[x].resize(n+1) , len[x] = n;
     78     for(int i=0;i<=n;i++)
     79         v[x][i] = a[i];
     80 }
     81 
     82 inline void merge() {
     83     while( pq.size() > 1 ) {
     84         const int y = pq.top().second; pq.pop();
     85         const int x = pq.top().second; pq.pop();
     86         mul(x,y) , v[y].resize(0);
     87         pq.push( make_pair(len[x],x) );
     88     }
     89 }
     90 inline void prefac(int x) {
     91     *fac = 1;
     92     for(int i=1;i<=x;i++)
     93         fac[i] = fac[i-1] * i % mod;
     94     invfac[x] = getinv(fac[x]);
     95     for(int i=x-1;~i;i--)
     96         invfac[i] = invfac[i+1] * ( i + 1 ) % mod;
     97 }
     98 inline void getans() {
     99     int n , sum = 0 , exp = 1006632961;
    100     lli ans = 0;
    101     scanf("%d",&n);
    102     for(int i=1;i<=n;i++)
    103         scanf("%d",len+i) , sum += len[i];
    104     prefac(sum);
    105     for(int i=1;i<=n;i++) {
    106         v[i].resize(len[i]+1);
    107         for(int j=1;j<=len[i];j++)
    108             v[i][j] = c(len[i]-1,j-1) * invfac[j] % mod;
    109         pq.push( make_pair(len[i],i) );
    110     }
    111     merge();
    112     const int x = pq.top().second; pq.pop();
    113     for(int i=1;i<=len[x];i+=2)
    114         ans += v[x][i] * fac[i] % mod , ans %= mod;
    115     if( n == sum ) exp = n & 1;
    116     printf("%d %lld
    ",exp,ans);
    117 }
    118 
    119 int main() {
    120     static int t;
    121     scanf("%d",&t);
    122     while( t-- )
    123         getans();
    124     return 0;
    125 }
    View Code


    T3palindrome


    一开始想SAM乱搞发现会被abb坑掉(abb+a),然后交对排用的stringn^5暴力感觉不保险,于是写了一个30分的哈希。(后来发现string也能过...…)

    正解暂时弃坑辣!


    30分哈希代码:

     1 #pragma GCC optimize(3)
     2 #pragma GCC optimize("-funsafe-loop-optimizations")
     3 #pragma GCC optimize("-funroll-loops")
     4 #pragma GCC optimize("-fwhole-program")
     5 #pragma GCC target("avx")
     6 #include<cstdio>
     7 #include<cstring>
     8 #define ulli unsigned long long
     9 using namespace std;
    10 const int maxn=1e3+1e2;
    11 const ulli base = 233;
    12 const ulli mod = 2013265921;
    13 
    14 char s[maxn];
    15 ulli in[maxn],hsh1[maxn],hsh2[maxn],pows[maxn],ans;
    16 int n;
    17 
    18 inline void inithsh() {
    19     for(int i=1;i<=n;i++)
    20         in[i] = s[i] - 'a' + 1;
    21     for(int i=1;i<=n;i++)
    22         hsh1[i] = hsh1[i-1] * base + in[i];
    23     for(int i=n;i;i--)
    24         hsh2[i] = hsh2[i+1] * base + in[i];
    25     *pows = 1;
    26     for(int i=1;i<=n;i++)
    27         pows[i] = pows[i-1] * base;
    28 }
    29 inline ulli segment1(int st,int ed) {
    30     --st;
    31     return hsh1[ed] - hsh1[st] * pows[ed-st];
    32 }
    33 inline ulli segment2(int st,int ed) {
    34     ++ed;
    35     return hsh2[st] - hsh2[ed] * pows[ed-st];
    36 }
    37 inline ulli merge1(int sx,int tx,int sy,int ty) {
    38     return segment1(sx,tx) * pows[ty-sy+1] + segment1(sy,ty);
    39 }
    40 inline ulli merge2(int sx,int tx,int sy,int ty) {
    41     return segment2(sy,ty) * pows[tx-sx+1] + segment2(sx,tx);
    42 }
    43 inline bool judge(int sx,int tx,int sy,int ty) {
    44     return merge1(sx,tx,sy,ty) == merge2(sx,tx,sy,ty);
    45 }
    46 
    47 int main() {
    48     scanf("%s",s+1);
    49     n = strlen(s+1);
    50     inithsh();
    51     for(int sx=1;sx<=n;++sx) {
    52         for(int tx=sx;tx<=n;++tx)
    53             for(int sy=1;sy<=n;++sy)
    54                 for(int ty=sy;ty<=n;++ty)
    55                     if( judge(sx,tx,sy,ty) )
    56                         ans += tx - sx + ty - sy + 2;
    57         ans %= mod;
    58     }
    59     
    60     printf("%llu
    ",ans);
    61     
    62     return 0;
    63 }
    View Code


    最后上ranking,反正T2T3谁也不会就是了。


  • 相关阅读:
    最小生成树
    负环详解
    P2053 [SCOI2007]修车
    P3254 圆桌问题
    P3114 [USACO15JAN]踩踏Stampede
    SP1043 GSS1
    SP2713 GSS4
    导出mysql内数据 python建倒排索引
    社团管理系统——总结报告
    北京地铁出行线路规划——代码实现
  • 原文地址:https://www.cnblogs.com/Cmd2001/p/8367369.html
Copyright © 2011-2022 走看看