• 2019牛客多校第二场


    比赛总结:

    看错F题意@byf

    要勇于打表找规律

    题解(不定更新)

     A EddyWalker

    B EddyWalker2

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define rep(i,a,n) for (int i=a;i<n;i++)
      4 #define per(i,a,n) for (int i=n-1;i>=a;i--)
      5 #define pb push_back
      6 #define mp make_pair
      7 #define all(x) (x).begin(),(x).end()
      8 #define fi first
      9 #define se second
     10 #define SZ(x) ((int)(x).size())
     11 typedef vector<int> VI;
     12 typedef long long ll;
     13 typedef long long LL;
     14 typedef pair<int,int> PII;
     15 const ll mod=1000000007;
     16 ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
     17 // head
     18  
     19 ll n;
     20 namespace linear_seq {
     21     const int N=10010;
     22     ll res[N],base[N],_c[N],_md[N];
     23  
     24     vector<int> Md;
     25     void mul(ll *a,ll *b,int k) {
     26         rep(i,0,k+k) _c[i]=0;
     27         rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
     28         for (int i=k+k-1;i>=k;i--) if (_c[i])
     29             rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
     30         rep(i,0,k) a[i]=_c[i];
     31     }
     32     int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
     33         ll ans=0,pnt=0;
     34         int k=SZ(a);
     35         assert(SZ(a)==SZ(b));
     36         rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
     37         Md.clear();
     38         rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
     39         rep(i,0,k) res[i]=base[i]=0;
     40         res[0]=1;
     41         while ((1ll<<pnt)<=n) pnt++;
     42         for (int p=pnt;p>=0;p--) {
     43             mul(res,res,k);
     44             if ((n>>p)&1) {
     45                 for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
     46                 rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
     47             }
     48         }
     49         rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
     50         if (ans<0) ans+=mod;
     51         return ans;
     52     }
     53     VI BM(VI s) {
     54         VI C(1,1),B(1,1);
     55         int L=0,m=1,b=1;
     56         rep(n,0,SZ(s)) {
     57             ll d=0;
     58             rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
     59             if (d==0) ++m;
     60             else if (2*L<=n) {
     61                 VI T=C;
     62                 ll c=mod-d*powmod(b,mod-2)%mod;
     63                 while (SZ(C)<SZ(B)+m) C.pb(0);
     64                 rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
     65                 L=n+1-L; B=T; b=d; m=1;
     66             } else {
     67                 ll c=mod-d*powmod(b,mod-2)%mod;
     68                 while (SZ(C)<SZ(B)+m) C.pb(0);
     69                 rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
     70                 ++m;
     71             }
     72         }
     73         return C;
     74     }
     75     int gao(VI a,ll n) {
     76         VI c=BM(a);
     77         c.erase(c.begin());
     78         rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
     79         return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
     80     }
     81 };
     82  
     83 int main() {
     84     vector<int>v;
     85     int t;
     86     scanf("%d",&t);
     87     int k;LL n;
     88     while(t--)
     89     {
     90         scanf("%d%lld",&k,&n);
     91         if(n==-1)
     92         {
     93             printf("%lld
    ",2LL*powmod(k+1,mod-2)%mod);
     94             continue;
     95         }
     96         v.clear();
     97         ll ook=powmod(k,mod-2);
     98         v.push_back(1);
     99         for(int i=1;i<=2*k+1;i++)
    100         {
    101             ll pa=0;
    102             for(int j=max(0,i-k);j<i;j++) pa=(pa+1ll*v[j]*ook)%mod;
    103             v.push_back(int(pa%mod));
    104         }
    105         printf("%lld
    ",1LL * linear_seq::gao(v,n) % mod);
    106     }
    107 }
    View Code

    C Go on Strike!

    D Kth Minimum Clique

     题解:https://blog.csdn.net/liufengwei1/article/details/97009245

     1 #include<bits/stdc++.h>
     2 #define maxl 110
     3 using namespace std;
     4 
     5 int n,k;
     6 long long ans;
     7 long long a[maxl];
     8 int mp[maxl][maxl];
     9 bitset <maxl> b[maxl];
    10 char ch[maxl];
    11 struct node
    12 {
    13     long long w;
    14     int id;
    15     bitset <maxl> s;
    16     bool operator > (const node &y)const
    17     {
    18         return w>y.w;
    19     }
    20 };
    21 priority_queue<node,vector<node>,greater<node> >q;
    22 
    23 inline void prework()
    24 {
    25     scanf("%d%d",&n,&k);
    26     for(int i=0;i<n;i++)
    27         scanf("%lld",&a[i]);
    28     for(int i=0;i<n;i++)
    29     {
    30         scanf("%s",ch);
    31         for(int j=0;j<n;j++)
    32         {
    33             mp[i][j]=ch[j]-'0';
    34             b[i][j]=mp[i][j];
    35         }
    36     }
    37 }
    38 
    39 inline void mainwork()
    40 {
    41     node d;bitset <maxl> ds;
    42     q.push(node{0,0,ds});
    43     
    44     while(k>0 && !q.empty())
    45     {
    46         d=q.top();q.pop();
    47         k--;
    48         if(!k)
    49         {
    50             ans=d.w;
    51             return;
    52         }
    53         for(int i=d.id;i<n;i++)
    54         if(!d.s[i] && (d.s&b[i])==d.s)
    55         {
    56             d.s[i]=1;
    57             q.push(node{a[i]+d.w,i,d.s});
    58             d.s[i]=0;
    59         }
    60     }
    61     ans=-1;
    62 }
    63 
    64 inline void print()
    65 {
    66     printf("%lld",ans);    
    67 }
    68 
    69 int main()
    70 {
    71     prework();
    72     mainwork();
    73     print();
    74     return 0;
    75 }
    View Code

    E MAZE

    F Partition problem

    题解:https://blog.csdn.net/liufengwei1/article/details/96729137

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3  
     4 int n;
     5 long long ans;
     6 int aa[30],bb[30];
     7 int v[30][30];
     8 long long f[30][1<<18];
     9 long long sum[30];
    10 int num[1<<18];
    11  
    12 inline void prework()
    13 {
    14     for(int i=0,x=1;i<18;i++,x<<=1)
    15         num[x]=i;
    16     scanf("%d",&n);
    17     for(int i=0;i<2*n;i++)  
    18         for(int j=0;j<2*n;j++)
    19             scanf("%d",&v[i][j]),sum[i+1]+=v[i][j];
    20     for(int i=1;i<=2*n;i++)
    21         sum[i]=sum[i-1]+sum[i];
    22     int l,s,d;
    23     for(int i=0;i<2*n;i++)
    24     {
    25         l=1<<(min(2*n,18));
    26         for(int j=1;j<l;j++)
    27         {
    28             s=j;
    29             while(s)
    30             {
    31                 d=s&-s;
    32                 f[i][j]+=v[i][num[d]];
    33                 s-=d;  
    34             }
    35         }
    36     }
    37 }
    38  
    39 inline void dfs(int k,int as,int bs,int acnt,long long w)
    40 {
    41     if(acnt+2*n-1-k+1<n || k-acnt+2*n-1-k+1<n)
    42         return;
    43     if(w+sum[2*n]-sum[k+1-1]<ans)  
    44         return;
    45     if(w>ans)
    46         ans=w;
    47     if(k>=2*n)
    48         return;
    49     long long tmp=0;int tas,tbs;
    50     if(k>=18)
    51     {
    52         aa[++aa[0]]=k;
    53         tmp=w+f[k][bs];
    54         for(int i=1;i<=bb[0];i++)
    55             tmp+=v[k][bb[i]];
    56         dfs(k+1,as,bs,acnt+1,tmp);
    57         aa[aa[0]--]=0;
    58          
    59         bb[++bb[0]]=k;
    60         tmp=w+f[k][as];
    61         for(int i=1;i<=aa[0];i++)
    62             tmp+=v[k][aa[i]];
    63         dfs(k+1,as,bs,acnt,tmp);
    64         bb[bb[0]--]=0;
    65     }
    66     else
    67     {
    68         dfs(k+1,as|(1<<k),bs,acnt+1,w+f[k][bs]);
    69         dfs(k+1,as,bs|(1<<k),acnt,w+f[k][as]);
    70     }
    71 }
    72  
    73 inline void mainwork()
    74 {
    75     dfs(0,0,0,0,0);
    76 }
    77  
    78 inline void print()
    79 {
    80     printf("%lld",ans);
    81 }
    82  
    83 int main()
    84 {
    85     prework();
    86     mainwork();
    87     print();
    88     return 0;
    89 }
    View Code

    G Polygons

    H Second Large Rectangle

    题解:https://blog.csdn.net/liufengwei1/article/details/96730426

      1 #include<bits/stdc++.h>
      2 #define maxl 1010
      3  
      4 using namespace std;
      5  
      6 int n,m,top,mx,mx1,my1,mx2,my2,secmx;
      7 int s[maxl],h[maxl],l[maxl],r[maxl];
      8 int a[maxl][maxl];
      9 char ch[maxl];
     10  
     11 inline void prework()
     12 {
     13     scanf("%d%d",&n,&m);
     14     for(int i=1;i<=n;i++)
     15     {
     16         scanf("%s",ch+1);
     17         for(int j=1;j<=m;j++)
     18             a[i][j]=ch[j]-'0';
     19     }
     20 }
     21  
     22 inline void solve1()
     23 {
     24     mx=0;int tmp;
     25     for(int i=1;i<=m;i++)
     26         h[i]=0;
     27     for(int i=1;i<=n;i++)
     28     {
     29         for(int j=1;j<=m;j++)
     30         if(a[i][j]==1)
     31             h[j]++;
     32         else
     33             h[j]=0;
     34         top=0;
     35         for(int j=1;j<=m;j++)
     36         {
     37             while(top>0 && h[s[top]]>h[j])
     38                 r[s[top]]=j-1,--top;
     39             l[j]=s[top]+1;
     40             s[++top]=j;
     41         }
     42         while(top>0)
     43             r[s[top]]=m,--top;
     44         for(int j=1;j<=m;j++)
     45         if(h[j])
     46         {
     47             tmp=h[j]*(r[j]-l[j]+1);
     48             if(tmp>mx)
     49             {
     50                 mx=tmp;
     51                 mx1=i-h[j]+1;my1=l[j];
     52                 mx2=i;my2=r[j];
     53             }
     54         }
     55     }
     56 }
     57  
     58 inline void solve2()
     59 {
     60     secmx=0;int tmp,tx1,tx2,ty1,ty2;
     61     for(int i=1;i<=m;i++)
     62         h[i]=0;
     63     for(int i=1;i<=n;i++)
     64     {
     65         for(int j=1;j<=m;j++)
     66         if(a[i][j]==1)
     67             h[j]++;
     68         else
     69             h[j]=0;
     70         top=0;
     71         for(int j=1;j<=m;j++)
     72         {
     73             while(top>0 && h[s[top]]>h[j])
     74                 r[s[top]]=j-1,--top;
     75             l[j]=s[top]+1;
     76             s[++top]=j;
     77         }
     78         while(top>0)
     79             r[s[top]]=m,--top;
     80         for(int j=1;j<=m;j++)
     81         if(h[j])
     82         {
     83             tx1=i-h[j]+1;ty1=l[j];
     84             tx2=i;ty2=r[j];
     85             tmp=h[j]*(r[j]-l[j]+1);
     86             if(mx1!=tx1 || my1!=ty1 || mx2!=tx2 || my2!=ty2)
     87                 secmx=max(tmp,secmx);
     88             secmx=max(secmx,(h[j]-1)*(r[j]-l[j]+1));
     89             secmx=max(secmx,h[j]*(r[j]-l[j]));
     90         }
     91     }
     92 }
     93  
     94 inline void mainwork()
     95 {
     96     solve1();
     97     solve2();
     98 }
     99  
    100 inline void print()
    101 {
    102     printf("%d
    ",secmx);
    103 }
    104  
    105 int main()
    106 {
    107     prework();
    108     mainwork();
    109     print();
    110     return 0;  
    111 }
    View Code

    I Inside A Rectangle

    J  Subarray

    题解:https://blog.csdn.net/liufengwei1/article/details/96836978

     1 //牛逼网友的J 
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 const int INF = 0x3f3f3f3f;
     6 const int MAXN = 10000000, MAXM = 1000000;
     7  
     8 int l[MAXM + 5], r[MAXM + 5], f[MAXM + 5], g[MAXM + 5];
     9 int sum[MAXN * 3 + 5], b[MAXN * 3 + 5], c[MAXN * 3 + 5];
    10  
    11 int main() 
    12 {
    13     int n;
    14     scanf("%d",&n);
    15     for(int i=1;i<=n;i++)
    16         scanf("%d%d",&l[i],&r[i]);
    17     f[1]=r[1]-l[1]+1;
    18     //f[i]以i段右端点为结尾的能构造出的最大的前缀和
    19     for(int i=2;i<=n;i++)
    20         f[i]=max(0,f[i-1]-(l[i]-r[i-1]-1))+r[i]-l[i]+1;
    21     //0:以i-1段右端点结尾的能构造出的最大的前缀和都不足够跨过[i-1,i]之间的-1
    22     //f[i - 1] - (l[i] - r[i - 1] - 1):跨过之后还剩下多少贡献给这段
    23     g[n]=r[n]-l[n]+1;
    24     //g[i]以i段左端点为开头的能构造出的最大的前缀和
    25     for(int i=n-1;i>=1;i--)
    26         g[i]=max(0,g[i+1]-(l[i+1]-r[i]-1))+r[i]-l[i]+1;
    27     //ERR1(f, n);
    28     //ERR1(g, n);
    29     int i=1,base=10000000;
    30     ll ans=0;
    31     while(i<=n) 
    32     {
    33         int j=i+1;
    34         while(j<=n && g[j]+f[j-1]>=l[j]-r[j - 1]-1) {
    35             //说明这个[j-1,j]之间的-1段可以因为两侧的f[j-1]和g[j]足够大而连接起来
    36             j++;
    37         }
    38         j--;
    39         //此时j是从i开始最远能够连接到的区间
    40         int left=max(0,l[i]-g[i]),right=min(1000000000-1,r[j]+f[j]);
    41         //left,right是至少会产生一个贡献的范围
    42         //ERR(left, right);
    43         int t=i,mi=INF,mx=0;
    44         sum[0]=0;
    45         for(int k=left;k<=right;k++) 
    46         {
    47             //统计这一整段可连接区间的前缀和
    48             if(k>=l[t] && k<=r[t])
    49                 sum[k-left+1]=sum[k-left]+1;
    50             else
    51                 sum[k-left+1]=sum[k-left]-1;
    52             if(k==r[t])
    53                 t++;
    54             mi=min(mi,sum[k-left+1]+base);
    55             mx=max(mx,sum[k-left+1]+base);
    56             //b记录前缀和出现过的次数
    57             b[sum[k-left+1]+base]++;
    58         }
    59         //ERR1(sum, right);
    60         //b记录前缀和出现过的次数的后缀和
    61         for(int k=mx-1;k>=mi;k--)
    62             b[k]+=b[k+1];
    63         //包含最左侧点的贡献
    64         ans+=b[base+1];
    65         for(int k=left;k<=right;k++) {
    66             t=sum[k-left+1]+base;
    67             //t表示k位置sum的值
    68             //b[t+1]比t大的值的个数
    69             //c[t+1]比在k位置左侧的比t大的值的个数的lazy
    70             b[t+1]-=c[t+1]; //把lazy加上去
    71             c[t]+=c[t+1]+1; //lazy标记下移
    72             c[t+1] = 0; //清空lazy
    73             ans+=b[t+1];
    74         }
    75         for(int k=mi;k<=mx;k++)
    76             b[k]=0,c[k]=0;
    77         i=j+1;
    78     }
    79     printf("%lld", ans);
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    MySQL Backup mysqldump 常用选项与主要用法--转发
    openssl 之RSA加密
    Windows 之Dll/lib导出
    缓存雪崩、击穿、穿透
    时间复杂度
    分布式事务
    mysql主从复制与读写分离
    什么是消息队列?
    微服务架构演化
    高并发问题常规思路
  • 原文地址:https://www.cnblogs.com/csushl/p/11231720.html
Copyright © 2020-2023  润新知