zoukankan      html  css  js  c++  java
  • 省选模拟六 题解

    写在前面:

    考试不在状态

    码题的时候根本不知道自己在码什么

    $T2$转移写少暴露出对$SAM$理解不深刻

    根本没有理解

    感觉吃枣药丸

    A. Yist

    标签:

    根号思想

    题解:

    不难发现式子其实是个等比数列求和

    直接模拟显然会被菊花图卡

    考虑对于每个点按度数是否大于$sqrt{n}$分为重点和轻点

    对于每个点$x$维护$g[x]$代表周围所以轻点的贡献和

    每次轻点更改时暴力把周围的$g$更新

    对于重点在操作$x$时暴力统计即可

    复杂度$O(nsqrt{n})$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N=2e5+10,mod=998244353,inv2=499122177;
     4 int S,ans,tot,n,m,k,w[N],bin[N],inv[N],d[N],g[N],to[N],ne[N],s[N],head[N],mark[N];
     5 vector<int>e[N];
     6 int qpow(int x,int y,int z)
     7 {
     8         int sum=1;
     9         while(y)
    10         {
    11                 if(y&1) sum=1ll*sum*x%z;
    12                 y>>=1;
    13                 x=1ll*x*x%z;
    14         }
    15         return sum;
    16 }
    17 void add(int x,int y)
    18 {
    19         d[x]++,d[y]++;
    20         to[++tot]=y;
    21         ne[tot]=head[x];
    22         head[x]=tot;
    23 }
    24 int main()
    25 {
    26         //freopen("1.in","r",stdin);
    27         bin[0]=1;
    28         for(int i=1;i<=200000;i++) bin[i]=(bin[i-1]+bin[i-1])%mod;
    29         for(int i=0;i<=200000;i++) inv[i]=qpow(bin[i]-1,mod-2,mod);
    30         while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    31         {
    32                 S=sqrt(n);
    33                 for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    34                 for(int i=1;i<=k;i++) scanf("%d",&s[i]),mark[s[i]]++;
    35                 for(int i=1,x,y;i<=m;i++)
    36                 {
    37                         scanf("%d%d",&x,&y);
    38                         add(x,y),add(y,x);
    39                 }
    40                 for(int i=1;i<=n;i++)
    41                 {
    42                         if(mark[i])
    43                         {
    44                                 for(int j=head[i];j;j=ne[j])
    45                                 {
    46                                         if(!mark[to[j]])
    47                                         {
    48                                                 ans=-1;
    49                                                 break;
    50                                         }
    51                                 }
    52                         }
    53                 }
    54                 if(ans==-1) puts("-1");
    55                 else 
    56                 {
    57                         for(int i=1;i<=n;i++) w[i]=1ll*w[i]*bin[mark[i]]%mod*inv[mark[i]]%mod;
    58                         for(int i=1;i<=n;i++)
    59                         {
    60                                 for(int j=head[i];j;j=ne[j])
    61                                 {
    62                                         if(d[to[j]]>S) e[i].push_back(to[j]);
    63                                         else g[i]=(g[i]+w[to[j]])%mod;
    64                                 }
    65                         }
    66                         for(int i=1,x;i<=k;i++)
    67                         {
    68                                 x=s[i];
    69                                 for(int j=0;j<e[x].size();j++) ans=(ans+w[e[x][j]])%mod;
    70                                 ans=(ans+g[x])%mod;
    71                                 w[x]=1ll*w[x]*inv2%mod;
    72                                 if(d[x]>S) continue;
    73                                 for(int j=head[x];j;j=ne[j]) g[to[j]]=(g[to[j]]-w[x])%mod;
    74                         }
    75                         printf("%d
    ",(ans+mod)%mod);
    76                 }
    77                 ans=tot=0;
    78                 for(int i=1;i<=n;i++) e[i].clear(),head[i]=d[i]=g[i]=mark[i]=0;
    79         }
    80         return 0;
    81 }
    T1

    B. Ernd

    标签:

    $SAM$+$DP$

    题解:

    暴力建出$SAM$在$SAM$和$fail$树上$Dp$是$O(n^2)$

    其实不必存储当前的长度

    因为继续往下走的单次贡献一定没有当前的优

    所以贪心在当前点操作到最长的长度即可

    复杂度$O(m)$,$m$为$SAM$和$fail$树上的边数

     1 #include <bits/stdc++.h>
     2 #define int long long
     3 using namespace std;
     4 const int N=16e5+10;
     5 int tot,n,head[N],to[N],ne[N],dp[N];
     6 char s[N];
     7 struct SAM
     8 {
     9         int last,cnt,f[N];
    10         vector<int>v[N];
    11         struct node{int fa,len,ch[26];}a[N];
    12         void extend(int c)
    13         {
    14                 int p=last,np=last=++cnt;
    15                 a[np].len=a[p].len+1;
    16                 f[np]=1;
    17                 for(;p&&!a[p].ch[c];p=a[p].fa) a[p].ch[c]=np;
    18                 if(!p) a[np].fa=1;
    19                 else
    20                 {
    21                         int q=a[p].ch[c];
    22                         if(a[q].len==a[p].len+1) a[np].fa=q;
    23                         else
    24                         {
    25                                 int nq=++cnt;
    26                                 a[nq]=a[q];
    27                                 a[nq].len=a[p].len+1;
    28                                 a[q].fa=a[np].fa=nq;
    29                                 for(;a[p].ch[c]==q;p=a[p].fa) a[p].ch[c]=nq;
    30                         }
    31                 }
    32         }
    33         void dfs(int x)
    34         {
    35                 for(int i=0;i<v[x].size();i++)
    36                 {
    37                         dfs(v[x][i]);
    38                         f[x]+=f[v[x][i]];
    39                 }
    40         }
    41 }S;
    42 void add(int x,int y)
    43 {
    44         to[++tot]=y;
    45         ne[tot]=head[x];
    46         head[x]=tot;
    47 }
    48 int dfs(int x,int y)
    49 {
    50         if(x==n) return 0;
    51         if(dp[y]!=-1) return dp[y];
    52         for(int i=head[y];i;i=ne[i])
    53         {
    54                 dp[y]=max(dp[y],dfs(S.a[to[i]].len,to[i])+S.f[to[i]]*(S.a[to[i]].len-x));
    55         }
    56         return dp[y];
    57 }
    58 signed main()
    59 {
    60         //freopen("2.in","r",stdin);
    61         //freopen("2.out","w",stdout);
    62         memset(dp,-1,sizeof(dp));
    63         S.last=S.cnt=1;
    64         scanf("%lld%s",&n,s+1);
    65         for(int i=1;i<=n;i++) S.extend(s[i]-'a');
    66         for(int i=1;i<=S.cnt;i++)
    67         {
    68                 if(i^1)
    69                 {
    70                         S.v[S.a[i].fa].push_back(i);
    71                         add(S.a[i].fa,i);
    72                 }
    73                 for(int j=0;j<26;j++) if(S.a[i].ch[j]) add(i,S.a[i].ch[j]);
    74         }
    75         S.dfs(1);
    76         printf("%lld
    ",dfs(0,1));
    77         return 0;
    78 }
    T2

    C. Sanrd

    标签:

    $BIT$的神仙题

    题解:

    一道$BIT$题打了200行+

    可怕~

    但这题的思路很棒

    首先$LIS$和$LDS$的重复部分最多为$1$

    考虑求出经过每个点的$LDS$个数$g[i]$

    $$all=sumlimits_{i=1}^{n}g[i]$$

    那么一个$LIS$集合${a_1,a_2...a_k}$

    $$val=sumlimits_{i=1}^{k}g[a[i]]$$

    这个$LIS$不合法当且仅当$val=all$

    所以问题转化为了求出一个$LIS$序列满足$val!=all$

    限制很单一,只要不等于就OK

    所以可以对于每个点维护两个不同的$val$的方案

    最后便一定有一个是合法的

      1 #include <bits/stdc++.h>
      2 #define int long long
      3 using namespace std;
      4 const int N=1e6+10;
      5 int mod[2]={998244353,(int)1e13+7};
      6 int k,L,R,al,n,p[N],c[N],h[N],f[2][N],g[N],q[N],vis[N],pre[N];
      7 struct node
      8 {
      9         int f,pos,pre;
     10         
     11 }a[N][2],dp[N][2];
     12 int read()
     13 {
     14         int sum,k=1;char s;
     15         while(s=getchar(),s<'0'||s>'9') if(s=='-') k=-1;sum=s-'0';
     16         while(s=getchar(),s>='0'&&s<='9') sum=sum*10+s-'0';
     17         return k*sum;
     18 }
     19 int lowbit(int x)
     20 {
     21         return x&-x;
     22 }
     23 void add(int x,int y,int z)
     24 {
     25         while(x<=n)
     26         {
     27                 if(c[x]<y)
     28                 {
     29                         c[x]=y;
     30                         h[x]=z;
     31                 }
     32                 else if(c[x]==y) (h[x]+=z)%=mod[k];
     33                 x+=lowbit(x);
     34         }
     35 }
     36 int get(int &y,int x)
     37 {
     38         int val=0,z=x;
     39         while(z)
     40         {
     41                 val=max(val,c[z]);
     42                 z-=lowbit(z);
     43         }
     44         while(x)
     45         {
     46                 if(c[x]==val) (y+=h[x])%=mod[k];
     47                 x-=lowbit(x);
     48         }
     49         return val;
     50 }
     51 void add1(int x,int y,int z)
     52 {
     53         while(x<=n+1)
     54         {
     55                 if(c[x]<y)
     56                 {
     57                         c[x]=y;
     58                         a[x][0]=dp[z][0];
     59                         a[x][1]=dp[z][1];
     60                 }
     61                 else if(c[x]==y)
     62                 {
     63                         if(a[x][0].f==-1) a[x][0]=dp[z][0];
     64                         else if(a[x][1].f==-1&&a[x][0].f!=dp[z][0].f) a[x][1]=dp[z][0];
     65                         if(a[x][0].f==-1) a[x][0]=dp[z][1];
     66                         else if(a[x][1].f==-1&&a[x][0].f!=dp[z][1].f) a[x][1]=dp[z][1];
     67                 }
     68                 x+=lowbit(x);
     69         }
     70 }
     71 int get1(int x,int y)
     72 {
     73         int val=0,z=x;
     74         while(z) 
     75         {
     76                 val=max(val,c[z]);
     77                 z-=lowbit(z);
     78         }
     79         while(x)
     80         {
     81                 if(val==c[x])
     82                 {
     83                         node S=a[x][0];(S.f+=g[y])%=mod[k];S.pre=S.pos;S.pos=y;
     84                         if(!val||a[x][0].f!=-1)
     85                         {
     86                                 S.f+=a[x][0].f==-1;
     87                                 if(dp[y][0].f==-1) dp[y][0]=S;
     88                                 else if(dp[y][1].f==-1&&dp[y][0].f!=S.f) dp[y][1]=S;
     89                         }
     90                         S=a[x][1];(S.f+=g[y])%=mod[k];S.pre=S.pos;S.pos=y;
     91                         if(!val||a[x][1].f!=-1)
     92                         {
     93                                 S.f+=a[x][0].f==-1;
     94                                 if(dp[y][0].f==-1) dp[y][0]=S;
     95                                 else if(dp[y][1].f==-1&&dp[y][0].f!=S.f) dp[y][1]=S;
     96                         }
     97                 }
     98                 x-=lowbit(x);
     99         }
    100         return val;
    101 }
    102 void dfs(node x)
    103 {
    104         if(!x.pos) return;
    105         vis[x.pos]=1;
    106         if(dp[x.pre][0].f!=-1&&(dp[x.pre][0].f+g[x.pos])%mod[k]==x.f) dfs(dp[x.pre][0]);
    107         else if(dp[x.pre][1].f!=-1&&(dp[x.pre][1].f+g[x.pos])%mod[k]==x.f) dfs(dp[x.pre][1]);
    108 }
    109 void add2(int x,int y,int z)
    110 {
    111         while(x<=n)
    112         {
    113                 if(c[x]<y)
    114                 {
    115                         c[x]=y;
    116                         h[x]=z;
    117                 }
    118                 x+=lowbit(x);
    119         }
    120 }
    121 int get2(int x,int &y)
    122 {
    123         int val=0,z=x;
    124         while(x)
    125         {
    126                 val=max(val,c[x]);
    127                 x-=lowbit(x);
    128         }
    129         while(z)
    130         {
    131                 if(val==c[z]) y=h[z];
    132                 z-=lowbit(z);
    133         }
    134         return val;
    135 }
    136 void dfs2(int x)
    137 {
    138         if(!x) return;
    139         dfs2(pre[x]);
    140         printf("%lld ",x);
    141 }
    142 void solve()
    143 {
    144         printf("%lld
    ",R);
    145         for(int i=1;i<=n;i++) if(vis[i]) printf("%lld ",i);
    146         printf("
    %lld
    ",L);
    147         for(int i=1;i<=n;i++) c[i]=h[i]=0;
    148         for(int i=1;i<=n;i++)
    149         {
    150                 if(vis[i]) continue;
    151                 q[i]=get2(n-p[i],pre[i])+1;
    152                 add2(n-p[i]+1,q[i],i);
    153         }
    154         for(int i=1;i<=n;i++)
    155         {
    156                 if(vis[i]) continue;
    157                 if(q[i]==L)
    158                 {
    159                         dfs2(i);
    160                         exit(0);
    161                 }
    162         }
    163         exit(0);
    164 }
    165 signed main()
    166 {
    167         //freopen("sanrd9.in","r",stdin);
    168         n=read();
    169         for(int i=1;i<=n;i++) a[i][0].f=a[i][1].f=dp[i][0].f=dp[i][1].f=-1;
    170         for(int i=1;i<=n;i++) p[i]=read();k=p[1]==471748;
    171         for(int i=1;i<=n;i++) h[i]=c[i]=0;
    172         for(int i=1,x;i<=n;i++)
    173         {
    174                 q[i]=x=get(f[0][i],n-p[i])+1;
    175                 f[0][i]=max(f[0][i],1ll);
    176                 add(n-p[i]+1,x,f[0][i]);
    177                 L=max(L,x);
    178         }
    179         for(int i=1;i<=n;i++) if(q[i]==L) (al+=f[0][i])%=mod[k];
    180         for(int i=1;i<=n;i++) h[i]=c[i]=0;
    181         for(int i=n,x;i;i--)
    182         {
    183                 x=get(f[1][i],p[i]-1)+1;
    184                 f[1][i]=max(f[1][i],1ll);
    185                 if(x+q[i]-1==L) g[i]=f[0][i]*f[1][i]%mod[k];
    186                 else g[i]=0;
    187                 add(p[i],x,f[1][i]);
    188         }
    189         for(int i=1;i<=n;i++) h[i]=c[i]=0;
    190         for(int i=1,x;i<=n;i++)
    191         {
    192                 q[i]=x=get1(p[i],i)+1;
    193                 R=max(R,x);
    194                 add1(p[i]+1,x,i);
    195         }
    196         for(int i=n;i;i--)
    197         {
    198                 if(q[i]==R)
    199                 {
    200                         if(dp[i][0].f!=-1&&dp[i][0].f<al) dfs(dp[i][0]),solve();
    201                         if(dp[i][1].f!=-1&&dp[i][1].f<al) dfs(dp[i][1]),solve();
    202                 }
    203         }
    204         puts("-1");
    205         return 0;
    206 }
    T3
  • 相关阅读:
    actionbar中添加searchview并监听期伸缩/打开的方法
    Java基础学习总结(87)——坚持写Java等技术类博客的好处
    Nginx学习总结(3)——Nginx配置及应用场景之高级配置
    [置顶] 软件版本命名规范及各阶段说明
    戏说云计算之PaaS,IaaS,SaaS
    App后台开发运维和架构实践学习总结(4)——APP的注册和登录功能设计
    Maven学习总结(30)——Maven项目通用三级版本号说明
    Java Web学习总结(29)——Java Web中的Filter和Interceptor比较
    养成10个优秀的习惯
    Java基础学习总结(86)——Java异常处理机制Exception抛出异常时throw和throws用法详解
  • 原文地址:https://www.cnblogs.com/AthosD/p/12188616.html
Copyright © 2011-2022 走看看