• 省选模拟6&7


    因为改题太慢,两篇总结合一块写了。

    馍旎6:

    抄了一套UR(的题目

    A. Yist

    根号算法。

    首先判-1即为判断是否有一个点能对其他点作贡献,且不存在于s序列中。

    考虑单个点的贡献,假如第一轮贡献为$a$,之后每一轮的的贡献即为$a*2^{cnt}$

    cnt为这个点在序列中出现的次数。然后这玩意拿等比数列求和就可以了。

    然后出题人随便造个菊花图就能卡死你。

    考虑根号算法,按每个点度数是否大于$sqrt{n}$分为大点和小点。

    对于每个大点,统计时暴力扫与它相连的大点统计贡献,

    大点同时累计自己对周围小点的贡献

    小点暴力扫所有出边统计贡献,同时接受大点贡献

     1 #include<bits/stdc++.h>
     2 #define N 400050
     3 #define pb push_back
     4 const int mod=998244353,inv2=499122177;
     5 using namespace std;
     6 int s[N],n,m,k;
     7 int w[N],d[N];
     8 int a[N],ts[N],val[N];
     9 vector<int>v[N],c[N];
    10 inline int qpow(int d,int z){
    11     int ret=1;
    12     for(;z;z>>=1,d=1ll*d*d%mod)
    13         if(z&1)ret=1ll*ret*d%mod;
    14     return ret;
    15 }
    16 inline bool judge(){
    17     static bool pd[N];
    18     memset(pd,false,sizeof(pd));
    19     for(int i=1;i<=k;++i)pd[s[i]]=1;
    20     for(int i=1;i<=n;++i)
    21         for(int j=v[i].size()-1;~j;--j)
    22             if(pd[i]&&!pd[v[i][j]]&&w[v[i][j]])
    23                 return true;
    24     return false;
    25 }
    26 bool cmp(const int &a,const int &b){
    27     return v[a].size()>v[b].size();
    28 }
    29 int main(){
    30     for(int i=1;i<=n;++i){
    31         v[i].clear();c[i].clear();
    32         ts[i]=1;a[i]=val[i]=d[i]=0;
    33     }
    34     if(scanf("%d%d%d",&n,&m,&k)==EOF)return 0;
    35     for(int i=1;i<=n;++i){
    36         scanf("%d",&w[i]);
    37         v[i].clear();c[i].clear();
    38         ts[i]=1,a[i]=val[i]=d[i]=0;
    39     }
    40     for(int i=1;i<=k;++i)scanf("%d",&s[i]);
    41     for(int i=1,x,y;i<=m;++i){
    42         scanf("%d%d",&x,&y);
    43         v[x].pb(y);v[y].pb(x);
    44     }
    45     if(judge()){puts("-1");return main();}
    46     const int sq=sqrt(n);
    47     for(int i=1;i<=n;++i){
    48         sort(v[i].begin(),v[i].end(),cmp);
    49         d[i]=v[i].size()>=sq?1:0;
    50     }
    51     for(int i=1;i<=n;++i)
    52         if(!d[i]){
    53             for(int j=0,sz=v[i].size();j<sz&&d[v[i][j]];++j)
    54                 c[i].pb(0);
    55         }
    56     int ans=0;
    57     
    58     for(int i=1,g;i<=k;++i){
    59         g=s[i];ts[g]<<=1;
    60         if(ts[g]>=mod)ts[g]-=mod;
    61         if(d[g]){
    62             ++val[g];
    63             for(int j=0,sz=v[g].size();j<sz&&d[v[g][j]];++j)
    64                 (a[v[g][j]]+=w[v[g][j]])%=mod;
    65         }
    66         else{
    67             for(int j=0,sz=v[g].size();j<sz;++j){
    68                 (a[v[g][j]]+=w[v[g][j]])%=mod;
    69                 if(d[v[g][j]]){
    70                     (a[g]+=1ll*w[g]*(val[v[g][j]]-c[g][j])%mod)%=mod;
    71                     c[g][j]=val[v[g][j]];
    72                 }
    73             }
    74         }
    75         w[g]=1ll*w[g]*inv2%mod;
    76     }
    77     for(int g=1;g<=n;++g)
    78         if(!d[g]){
    79             for(int j=0,sz=v[g].size();j<sz&&d[v[g][j]];++j)
    80                 (a[g]+=1ll*w[g]*(val[v[g][j]]-c[g][j])%mod)%=mod;
    81         }
    82     for(int i=1;i<=n;++i){
    83         ans+=1ll*a[i]*ts[i]%mod*qpow(ts[i]-1,mod-2)%mod;
    84         if(ans>=mod)ans-=mod;
    85     }
    86     cout<<ans<<endl;
    87     return main();
    88 }
    View Code

    B. Ernd

    $SAM+dp$

    在串前加字符相当于在$parent_tree$上走,在串后加字符相当于在$SAM$上走。

    发现对于$parent_tree$上一个节点,一定是把它先走到当前点的最大长度再转移。

    拓扑dp,最后输出$dp[las]$

     1 #include<bits/stdc++.h>
     2 #define N 400050
     3 #define ull unsigned long long
     4 using namespace std;
     5 int n,f[N];
     6 int du[N];
     7 long long dp[N],ans;
     8 char s[N];
     9 int tot=1,las=1;
    10 int he[N],ne[N],to[N],cnt;
    11 inline void addedge(int x,int y){
    12     to[++cnt]=y;ne[cnt]=he[x];he[x]=cnt;
    13 }
    14 struct node{
    15     int len,fa;
    16     int ch[26];
    17 }tr[N];
    18 inline void add(int c){
    19     int np=++tot,p=las;las=np;f[np]=1;
    20     tr[np].len=tr[p].len+1;
    21     for(;p&&!tr[p].ch[c];p=tr[p].fa)tr[p].ch[c]=np;
    22     if(!p)return tr[np].fa=1,void();
    23     int q=tr[p].ch[c];
    24     if(tr[q].len==tr[p].len+1)return tr[np].fa=q,void();
    25     int nq=++tot;tr[nq]=tr[q];
    26     tr[nq].len=tr[p].len+1;
    27     tr[q].fa=tr[np].fa=nq;
    28     for(;p&&tr[p].ch[c]==q;p=tr[p].fa)tr[p].ch[c]=nq;
    29 }
    30 inline void tope(){
    31     for(int i=1;i<=tot;++i)
    32         for(int j=0;j<26;++j)
    33             ++du[tr[i].ch[j]];
    34     queue<int>q;q.push(1);
    35     while(q.size()){
    36         int g=q.front();q.pop();
    37 //        printf("f[%d]=%d
    ",g,f[g]);
    38         dp[g]=max(dp[g],dp[tr[g].fa]+f[g]*(tr[g].len-tr[tr[g].fa].len));
    39         for(int i=0,t;i<26;++i){
    40             t=tr[g].ch[i];if(!t)continue;
    41             dp[t]=max(dp[t],dp[g]+1ll*f[t]*(tr[t].len-tr[g].len));
    42             --du[t];
    43             if(!du[t])q.push(t);
    44         }
    45     }
    46     ans=dp[las];
    47 }
    48 inline void dfs(int g){
    49     for(int i=he[g];i;i=ne[i])
    50         dfs(to[i]),f[g]+=f[to[i]];
    51 }
    52 int main(){
    53     scanf("%d%s",&n,s+1);
    54     for(int i=1;i<=n;++i)add(s[i]-'a');
    55     for(int i=2;i<=tot;++i)addedge(tr[i].fa,i);
    56     dfs(1);
    57     tope();
    58     cout<<ans<<endl;
    59     return 0;
    60 }
    View Code

    C. Sanrd

    大神题,改了一下午加一晚上加一早上才改过来。

    其实还是挺好理解的,就是代码难打

      1 #include<bits/stdc++.h>
      2 #define N 500050
      3 #define ull long long
      4 const int mod=998244353;
      5 using namespace std;
      6 int dp1[N],dp2[N],n,a[N],an1,an2,pr[N][2],pre[N];
      7 ull f[N],f2[N],al,w[N][2];
      8 struct BIT{
      9     int ct[N],po[N];
     10     inline void clear(){
     11         memset(ct,0,sizeof(int)*(n+1));
     12         memset(po,0,sizeof(int)*(n+1));
     13     }
     14     inline void add(int x,int v,int id=0){
     15         while(x){
     16             if(v>ct[x])
     17                 ct[x]=v,po[x]=id;
     18             x-=x&-x;
     19         }
     20     }
     21     inline int ask(int x){
     22         int ret=0;
     23         while(x<=n)
     24             ret=max(ret,ct[x]),x+=x&-x;
     25         return ret;
     26     }
     27     inline int ask2(int x){
     28         int ret=0,r2=0;
     29         while(x<=n){
     30             if(ct[x]>ret)ret=ct[x],r2=po[x];
     31             x+=x&-x;
     32         }
     33         return r2;
     34     }
     35 }b;
     36 struct BIT2{
     37     ull ct[N];int tim[N],cnt;
     38     inline void clear(){++cnt;}
     39     inline void add(int x,int v){
     40         while(x){
     41             if(tim[x]!=cnt)tim[x]=cnt,ct[x]=0;
     42             ct[x]+=v;x-=x&-x;
     43         }
     44     }
     45     inline ull ask(int x){
     46         ull ret=0;
     47         while(x<=n){
     48             if(tim[x]!=cnt)tim[x]=cnt,ct[x]=0;
     49             ret+=ct[x];
     50             x+=x&-x;
     51         }
     52         ret%=mod;
     53         return ret;
     54     }
     55 }b2;
     56 vector<int>v[N];
     57 #define pb push_back
     58 inline void init1(){
     59     b.clear();
     60     for(int i=1;i<=n;++i){
     61         dp2[i]=b.ask(a[i])+1;
     62         an2=max(an2,dp2[i]);
     63         b.add(a[i],dp2[i]);
     64         v[dp2[i]].push_back(i);
     65 //        printf("dp2[%d]=%d
    ",i,dp2[i]);
     66     }
     67     for(int i=0,sz=v[an2].size();i<sz;++i)f[v[an2][i]]=1;
     68     for(int i=an2;i>1;--i){
     69         int j=v[i-1].size()-1,k=v[i].size()-1;
     70         b2.clear();
     71         while(j>=0){
     72             while(k>=0&&v[i][k]>v[i-1][j]){
     73                 b2.add(a[v[i][k]],f[v[i][k]]);
     74                 --k;
     75             }
     76             f[v[i-1][j]]=b2.ask(1)-b2.ask(a[v[i-1][j]]);
     77             if(f[v[i-1][j]]<0)f[v[i-1][j]]+=mod;
     78             --j;
     79         }
     80     }
     81 //    for(int i=1;i<=n;++i)printf("f[%d]=%lld f2:%lld
    ",i,f[i],f2[i]);
     82     for(int i=0,sz=v[1].size();i<sz;++i)f2[v[1][i]]=1;
     83     for(int i=1;i<an2;++i){
     84         int j=0,k=0,sz=v[i].size(),sz2=v[i+1].size();
     85         b2.clear();
     86         while(j<sz2){
     87             while(k<sz&&v[i][k]<v[i+1][j]){
     88                 b2.add(a[v[i][k]],f2[v[i][k]]);
     89                 ++k;
     90             }
     91             f2[v[i+1][j]]=b2.ask(a[v[i+1][j]]);
     92             f[v[i+1][j]]*=f2[v[i+1][j]];
     93             f[v[i+1][j]]%=mod;
     94             ++j;
     95         }
     96     }
     97     for(int j=0,sz=v[an2].size();j<sz;++j)al+=f[v[an2][j]];
     98     al%=mod;
     99 //    for(int i=1;i<=n;++i)printf("f[%d]=%lld f2:%lld
    ",i,f[i],f2[i]);
    100 //    cout<<"al:"<<al<<endl;
    101 }
    102 int pd[N];
    103 struct BIT3{
    104     int ct[N];
    105     inline void add(int x,int v){
    106         while(x<=n){
    107             if(v>ct[x])ct[x]=v;
    108             x+=x&-x;
    109         }
    110     }
    111     inline int ask(int x){
    112         int ret=0;
    113         while(x)ret=max(ret,ct[x]),x-=x&-x;
    114         return ret;
    115     }
    116 }b3;
    117 struct BIT4{
    118     int q[N][2],ct[N];
    119     ull qq[N][2];
    120     inline void init(){
    121         for(int i=1;i<=n;++i)qq[i][0]=qq[i][1]=q[i][0]=q[i][1]=-1;
    122     }
    123     inline void add(int i){
    124         int x=a[i];
    125         while(x<=n){
    126             if(dp1[i]>ct[x]){
    127                 ct[x]=dp1[i];
    128                 q[x][0]=qq[x][0]=q[x][1]=qq[x][1]=-1;
    129             }
    130             if(ct[x]==dp1[i]&&qq[x][0]<0&&w[i][0]>=0){
    131                 q[x][0]=i;
    132                 qq[x][0]=w[i][0];
    133                 if(w[i][1]>=0){
    134                     q[x][1]=i;
    135                     qq[x][1]=w[i][1];
    136                 }
    137             }
    138             else if(ct[x]==dp1[i]&&qq[x][1]<0){
    139                 if(w[i][0]>=0&&w[i][0]!=qq[x][0]){
    140                     q[x][1]=i;
    141                     qq[x][1]=w[i][0];
    142                 }
    143                 if(w[i][1]>=0&&w[i][1]!=qq[x][0]){
    144                     q[x][1]=i;
    145                     qq[x][1]=w[i][1];
    146                 }
    147             }
    148             x+=x&-x;
    149         }
    150     }
    151     inline void ask(int i){
    152         int x=a[i];
    153         while(x){
    154             if(ct[x]==dp1[i]-1&&w[i][0]<0&&qq[x][0]>=0){
    155                 pr[i][0]=q[x][0];
    156                 w[i][0]=qq[x][0];
    157                 if(qq[x][1]>=0){
    158                     pr[i][1]=q[x][1];
    159                     w[i][1]=qq[x][1];
    160                 }
    161             }
    162             else if(ct[x]==dp1[i]-1&&w[i][1]<0&&qq[x][0]>=0){
    163                 if(qq[x][0]>=0&&qq[x][0]!=w[i][0]){
    164                     pr[i][1]=q[x][0];
    165                     w[i][1]=qq[x][0];
    166                 }
    167                 if(qq[x][1]>=0&&qq[x][1]!=w[i][0]){
    168                     pr[i][1]=q[x][1];
    169                     w[i][1]=qq[x][1];
    170                 }
    171             }
    172             x-=x&-x;
    173         }
    174     }
    175 }b4;
    176 inline void init2(){
    177     b4.init();
    178     for(int i=1;i<=n;++i){
    179         dp1[i]=b3.ask(a[i])+1;
    180         an1=max(an1,dp1[i]);
    181         b3.add(a[i],dp1[i]);
    182 //        printf("dp1[%d]=%d
    ",i,dp1[i]);
    183     }
    184     for(int i=1;i<=n;++i){
    185         w[i][0]=w[i][1]=-1;
    186         //if(dp1[i]!=1)
    187         b4.ask(i);
    188         if(w[i][0]>=0||dp1[i]==1){
    189             w[i][0]+=f[i];
    190             if(dp1[i]==1)++w[i][0];
    191         }
    192         if(w[i][1]>=0)w[i][1]+=f[i];
    193         w[i][0]%=mod;w[i][1]%=mod;
    194 //        printf("i:%d w0:%lld w1:%lld p0:%d p1:%d
    ",i,w[i][0],w[i][1],pr[i][0],pr[i][1]);
    195         b4.add(i);
    196     }
    197 }
    198 inline void dfs2(int g){
    199     if(!g)return;dfs2(pre[g]);
    200     printf("%d ",g);
    201 }
    202 inline void getans(){
    203     b.clear();
    204     printf("%d
    ",an1);
    205     for(int i=1;i<=n;++i){
    206         dp2[i]=0;
    207         if(pd[i]){
    208             printf("%d ",i);
    209             continue;
    210         }
    211         dp2[i]=b.ask(a[i])+1;
    212         pre[i]=b.ask2(a[i]);
    213         b.add(a[i],dp2[i],i);
    214 //        printf("pre[%d]=%d dp2:%d
    ",i,pre[i],dp2[i]);
    215     }
    216     printf("
    %d
    ",an2);
    217     for(int i=1;i<=n;++i)
    218         if(dp2[i]==an2)return dfs2(i);
    219 }
    220 inline void dfs(int g,ull t){
    221     if(!g)return getans();
    222     pd[g]=1;
    223     if((t+w[g][0])%mod!=al)dfs(pr[g][0],(t+f[g])%mod);
    224     else dfs(pr[g][1],(t+f[g])%mod);
    225 }
    226 int main(){
    227 //    freopen("sanrd2.in","r",stdin);freopen("my.out","w",stdout);
    228     scanf("%d",&n);
    229     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    230     init1();init2();
    231     memset(pd,0,sizeof(int)*(n+1));
    232     for(int i=1;i<=n;++i){
    233 //        cout<<i<<" "<<w[i][0]<<" "<<w[i][1]<<endl;
    234         if(dp1[i]==an1){
    235             if(w[i][0]!=-1&&w[i][0]!=al){
    236                 pd[i]=1;dfs(pr[i][0],f[i]);
    237                 return 0;
    238             }
    239             if(w[i][1]!=-1&&w[i][1]!=al){
    240                 pd[i]=1;dfs(pr[i][1],f[i]);
    241                 return 0;
    242             }
    243         }
    244     }
    245     puts("-1");return 0;
    246 }
    View Code

    馍旎7:

    A. 翻转硬币/星空

    原来写过一遍的题,然而也忘得差不多了。

    用到了差分的思想。

    考虑维护原01序列的差分序列。

    则原先的区间操作对应新的对有距离限制的两个点取反,

    转化为求最少多少次操作使得差分序列全为0。

    然后对每个为1点求出与其它为1的点的距离。

    然后跑状压dp就可以了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 #define reg register
     6 #define N 1100000
     7 using namespace std;
     8 int m,n,k;
     9 int a[120];
    10 int b[120];
    11 int pos[N];
    12 int g1[N];
    13 int g2[N];
    14 int dis[N][2];
    15 int w[1<<20];
    16 int dp[1<<20];
    17 void bfs()
    18 {
    19     memset(w,0x3f,sizeof(w));
    20     a[0]=0;
    21     for(int i=1;i<=n;++i)
    22         if(g2[i])a[++a[0]]=i,pos[i]=a[0];
    23     queue<int>q;
    24     int al,g,y;
    25     for(int i=1;i<=a[0];++i)
    26     {
    27         al=1;
    28         q.push(a[i]);dis[a[i]][0]=dis[a[i]][1]=0;
    29         while(al<a[0]&&q.size())
    30         {
    31             g=q.front();q.pop();
    32             for(int j=1;j<=m;++j)
    33             {
    34                 if(g-b[j]>0&&dis[g-b[j]][0]<i){
    35                     y=g-b[j];
    36                     dis[y][0]=i;
    37                     dis[y][1]=dis[g][1]+1;
    38                     if(pos[y]&&y!=a[i])
    39                         w[(1<<i-1)|(1<<pos[y]-1)]=dis[y][1];
    40                     else
    41                     q.push(y);
    42                 }
    43                 if(g+b[j]<=n&&dis[g+b[j]][0]<i){
    44                     y=g+b[j];
    45                     dis[y][0]=i;
    46                     dis[y][1]=dis[g][1]+1;
    47                     if(pos[y]&&y!=a[i])
    48                         w[(1<<i-1)|(1<<pos[y]-1)]=dis[y][1];
    49                     else
    50                     q.push(y);
    51                 }
    52             }
    53         }
    54         while(q.size())q.pop();
    55     }
    56 }
    57 void work()
    58 {
    59     memset(dp,0x3f,sizeof(dp));
    60     const int maxn=1<<a[0];dp[maxn-1]=0;
    61     reg int t1,t2;
    62     for(int i=maxn-1;i;--i)
    63         for(int j=i;j;j-=j&-j){
    64             t1=j&-j;
    65             for(int o=j-(j&-j);o;o-=o&-o){
    66                 t2=o&-o;
    67                 dp[i^t1^t2]=min(dp[i^t1^t2],dp[i]+w[t1|t2]);
    68             }
    69         }
    70     if(dp[0]>5000000)dp[0]=-1;
    71     cout<<dp[0]<<endl;
    72 }
    73 int main()
    74 {
    75     scanf("%d%d%d",&n,&k,&m);
    76     for(int i=1;i<=k;++i)
    77         scanf("%d",&a[i]),g1[a[i]]=1;
    78     ++n;
    79     for(int i=1;i<=m;++i)
    80         scanf("%d",&b[i]);
    81     for(int i=1;i<=n;++i)
    82         g2[i]=g1[i]^g1[i-1];
    83     bfs();
    84     work();
    85     return 0;
    86 }
    View Code

    B. 回文子串

    其实还是比较水的一道题,除了样例弱一点没啥

    然后维护答案可以用分快or线段树or树状数组。

    求回文串可以用$PAM or Manacher or hash$

    再加一个对拍就A了。上面的可以没有,但对拍必须有

      1 #include<bits/stdc++.h>
      2 #define N 50050
      3 #define ull unsigned long long
      4 using namespace std;
      5 int bl[N];
      6 char s[N];
      7 int n,sq,m,K;
      8 ull po[N],hs[N],hs2[N];
      9 const ull P=131;
     10 inline void geths(int l,int r){
     11     hs[l-1]=hs[r+1]=hs2[l-1]=hs2[r+1]=0;
     12     for(int i=l;i<=r;++i)hs[i]=hs[i-1]*P+s[i];
     13     for(int i=r;i>=l;--i)hs2[i]=hs2[i+1]*P+s[i];
     14 }
     15 struct seg1{
     16     int tag[N<<2];
     17     inline void down(int g){
     18         tag[g<<1]=tag[g<<1|1]=tag[g];
     19         tag[g]=0;
     20     }
     21     inline void change(int g,int l,int r,int x,int y,int c){
     22         if(l>y||r<x)return;
     23         if(l>=x&&r<=y){tag[g]=c;return;}
     24         const int m=l+r>>1;
     25         if(tag[g])down(g);
     26         change(g<<1,l,m,x,y,c);change(g<<1|1,m+1,r,x,y,c);
     27     }
     28     inline void getstr(int g,int l,int r,int x,int y){
     29         if(l>y||r<x)return;
     30         if(l==r){if(tag[g])s[l]=tag[g];return;}
     31         const int m=l+r>>1;if(tag[g])down(g);
     32         getstr(g<<1,l,m,x,y);getstr(g<<1|1,m+1,r,x,y);
     33     }
     34 }str;
     35 struct seg2{
     36     int sum[N<<2],tag[N<<2];
     37     inline void upd(int g){
     38         sum[g]=sum[g<<1]+sum[g<<1|1];
     39     }
     40     inline void down(int g,int l,int m,int r){
     41         tag[g<<1]=tag[g<<1|1]=tag[g];
     42         if(tag[g]==1)sum[g<<1]=m-l+1,sum[g<<1|1]=r-m;
     43         else sum[g<<1]=sum[g<<1|1]=0;
     44         tag[g]=0;
     45     }
     46     inline void change(int g,int l,int r,int x,int y,int v){
     47         if(l>y||r<x)return;
     48         if(l>=x&&r<=y){
     49             sum[g]=v>0?r-l+1:0;
     50             tag[g]=v;
     51             return;
     52         }
     53         const int m=l+r>>1;
     54         if(tag[g])down(g,l,m,r);
     55         change(g<<1,l,m,x,y,v);change(g<<1|1,m+1,r,x,y,v);
     56         upd(g);
     57     }
     58     inline int ask(int g,int l,int r,int x,int y){
     59         if(l>y||r<x)return 0;
     60         if(l>=x&&r<=y)return sum[g];
     61         const int m=l+r>>1;
     62         if(tag[g])down(g,l,m,r);
     63         return ask(g<<1,l,m,x,y)+ask(g<<1|1,m+1,r,x,y);
     64     }
     65 }tr[52];
     66 inline void init(){
     67     geths(1,n);
     68     for(int len=2;len<=K;++len){
     69         for(int i=len,j;i<=n;++i){
     70             j=i-len+1;
     71             if(hs[i]-hs[j-1]*po[len]==hs2[j]-hs2[i+1]*po[len])
     72                 tr[len].change(1,1,n,i,i,1);
     73         }
     74     }
     75 }
     76 inline void work1(int l,int r,int c){
     77     str.change(1,1,n,l,r,c);
     78     for(int len=2;len<=K;++len)
     79         tr[len].change(1,1,n,l+len-1,r,1);
     80     for(int len=2;len<=K;++len)
     81         tr[len].change(1,1,n,r+1,min(n,r+len-1),-1),
     82         tr[len].change(1,1,n,l,min(l+len-2,n),-1);
     83     int lm,rm;
     84 
     85     lm=max(r-K+2,1);rm=min(r+K,n);
     86     str.getstr(1,1,n,lm,rm);
     87     geths(lm,rm);
     88 //    printf("lm:%d rm:%d
    ",lm,rm);
     89     for(int len=2;len<=K;++len){
     90         for(int i=r+1,j;i<=rm;++i){
     91             j=i-len+1;
     92             if(j>r)break;
     93             if(j<=0)continue;
     94 //            puts("yes1");
     95             if(hs[i]-hs[j-1]*po[len]==hs2[j]-hs2[i+1]*po[len])
     96                 tr[len].change(1,1,n,i,i,1);//,cout<<i<<" ri "<<len<<endl;
     97         }
     98     }
     99     lm=max(l-K,1);rm=min(l+K-1,n);
    100     rm=min(rm,r);
    101     str.getstr(1,1,n,lm,rm);
    102     geths(lm,rm);
    103 //    printf("lm:%d rm:%d
    ",lm,rm);
    104     for(int len=2;len<=K;++len){
    105         for(int i=l,j;i<=rm;++i){
    106             j=i-len+1;
    107             if(j>=l)break;if(j<=0)continue;
    108 //            puts("yes2");
    109             if(hs[i]-hs[j-1]*po[len]==hs2[j]-hs2[i+1]*po[len])
    110                 tr[len].change(1,1,n,i,i,1);//,cout<<i<<" le "<<len<<endl;
    111         }
    112     }
    113 //    cout<<tr[2].sum[1]<<" "<<tr[3].sum[1]<<endl;
    114 }
    115 inline int getans(int l,int r){
    116     int ret=r-l+1;
    117     for(int len=2;len<=K;++len)
    118         ret+=tr[len].ask(1,1,n,l+len-1,r);
    119     return ret;
    120 }
    121 int main(){
    122     scanf("%s%d%d",s+1,&K,&m);
    123     n=strlen(s+1);sq=sqrt(n)+1;
    124     po[0]=1;for(int i=1;i<=n;++i)po[i]=po[i-1]*P;
    125     init();
    126     char S[3];
    127     for(int i=1,op,x,y;i<=m;++i){
    128 //        cout<<"i::"<<i<<endl;
    129         scanf("%d",&op);
    130         if(op==1){
    131             scanf("%d%d%s",&x,&y,S);
    132             work1(x,y,S[0]);
    133         }
    134         else{
    135             scanf("%d%d",&x,&y);
    136             printf("%d
    ",getans(x,y));
    137         }
    138     }
    139     return 0;
    140 }
    View Code

    C. 最大价值

    大神T3,%%%skyh考场切掉(然而没开long long 挂得还不如暴力xswl)

    当所选序列确定以后,一定是按a从小到大放。

    首先60分可以直接按a从小到大排序,然后大力dp。

    然后满分可以康这位大神的博客

     1 #include<bits/stdc++.h>
     2 #define N 300050
     3 #define LL long long
     4 using namespace std;
     5 struct node{
     6     LL a,b;
     7     friend bool operator <(const node &x,const node &y){
     8         return x.a==y.a?x.b<y.b:x.a<y.a;
     9     }
    10 }q[N];
    11 struct Splay{
    12     LL val[N],tag[N];
    13     int fa[N],ch[N][2],sz[N],rt,tot;
    14     inline int Get(int x){return ch[fa[x]][1]==x;}
    15     inline void upd(int g){sz[g]=sz[ch[g][0]]+sz[ch[g][1]]+1;}
    16     inline void rotate(int x){
    17         int y=fa[x],z=fa[y],p=Get(x),w=ch[x][p^1];
    18         if(w)fa[w]=y;ch[y][p]=w;
    19         if(z)ch[z][Get(y)]=x;fa[x]=z;
    20         fa[y]=x;ch[x][p^1]=y;
    21         upd(y);upd(x);
    22     }
    23     inline void push1(int g,LL v){if(!g||!v)return;val[g]+=v;tag[g]+=v;}
    24     inline void down(int x){push1(ch[x][0],tag[x]),push1(ch[x][1],tag[x]);tag[x]=0;}
    25     inline void pushall(int x){if(!x)return;down(x);}
    26     inline void splay(int x){while(fa[x])rotate(x);rt=x;}
    27     inline void insert(int i){
    28         ++tot;sz[tot]=1;
    29         if(!rt){rt=tot;val[rt]=q[i].b;return;}
    30         LL a=q[i].a,b=q[i].b;
    31         int x=rt,rk=0;
    32         while(1){
    33             down(x);
    34             if(a*(rk+sz[ch[x][0]])+b>val[x]){
    35                 if(ch[x][0])x=ch[x][0];
    36                 else{ch[x][0]=tot;fa[tot]=x;break;}
    37             }
    38             else{
    39                 rk+=sz[ch[x][0]]+1;
    40                 if(ch[x][1])x=ch[x][1];
    41                 else{ch[x][1]=tot;fa[tot]=x;break;}
    42             }
    43         }
    44         val[tot]=a*rk+b;
    45         splay(tot);push1(ch[rt][1],a);
    46     }
    47     inline void bl(int g,LL &ans){
    48         down(g);
    49         if(ch[g][0])bl(ch[g][0],ans);
    50         ans+=val[g];
    51         printf("%lld
    ",ans);
    52         if(ch[g][1])bl(ch[g][1],ans);
    53     }
    54 }s;
    55 namespace ae86{
    56     const int bufl=1<<15;
    57     char buf[bufl],*s=buf,*t=buf;
    58     inline int fetch(){
    59         if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}
    60         return*s++;
    61     }
    62     inline LL read(){
    63         LL a=0,b=1,c=fetch();
    64         while(!isdigit(c))b^=c=='-',c=fetch();
    65         while(isdigit(c))a=a*10+c-48,c=fetch();
    66         return b?a:-a;
    67     }
    68 }
    69 using ae86::read;
    70 int n;
    71 int main(){
    72     n=read();
    73     for(int i=1;i<=n;++i)q[i].a=read(),q[i].b=read();
    74     sort(q+1,q+n+1);LL ans=0;
    75     for(int i=1;i<=n;++i)s.insert(i);
    76     s.bl(s.rt,ans);
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    Codeforces Round #384 (Div. 2) 解题报告
    Codeforces Round #383 (Div. 2) 解题报告
    (DFS、bitset)AOJ-0525 Osenbei
    (DFS、全排列)POJ-3187 Backward Digit Sums
    自考新教材-p169
    自考新教材-p167
    自考新教材-p166
    自考新教材-p165
    自考新教材-p161
    自考新教材-p159
  • 原文地址:https://www.cnblogs.com/loadingkkk/p/12193429.html
Copyright © 2020-2023  润新知