zoukankan      html  css  js  c++  java
  • 【纪中受难记】——Day13:还有两天放假

    逃避现实,是一种短暂的解脱。

    10/0/0/0


    第一题题目有误,略过。


    Description

    俗话说“好命不如好名”,小h准备给他的宠物狗起个新的名字,于是他把一些英文的名字全抄下来了,写成一行长长的字符串,小h觉得一个名字如果是好名字,那么这个名字在这个串中既是前缀,又是后缀,即是这个名字从前面开始可以匹配,从后面开始也可以匹配,例如abc在 abcddabc中既是前缀,也是后缀,而ab就不是,可是长达4*10^5的字符让小h几乎昏过去了,为了给自己的小狗起个好名字,小h向你求救,并且他要求要将所有的好名字的长度都输出来。
     

    Input

    一行,要处理的字符串(都是小写字母)。

    Output

    一行若干个数字,从小到大输出,表示好名字的长度。
     

    Sample Input

    abcddabc

    Sample Output

    3 8
     

    Data Constraint

    这题让我捡起了许久没动的字符串算法。

      没啥好说的,就比较哈希值即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned long long ull;
     4 const int N=4e5+10;
     5 char c[N];
     6 ull h[N],g[N];
     7 void hash(){
     8     g[0]=1;
     9     for(int i=1;c[i];i++){
    10         h[i]=h[i-1]*131+c[i];
    11         g[i]=g[i-1]*131;
    12     }
    13 }
    14 int main(){
    15     scanf("%s",c+1);
    16     hash();
    17     ull len=strlen(c+1);
    18     for(ull i=1;i<=len;i++){
    19         ull tt=h[len]-h[len-i]*g[i];
    20         if(tt==h[i]) printf("%lld ",i);
    21     }
    22     return 0;
    23 }

    Description

    这个假期,小h在自家院子里种了许多花,它们围成了一个圈,从1..n编号(n<=100000),小h 对每盆花都有一个喜好值xi,(-1000<=xi<=1000),小h现在觉得这样一成不变很枯燥,于是他做了m(m<=100000)个改动,每次把第ki盘花改成喜好值为di的花,然后小h要你告诉他,在这个花圈中,连续的最大喜好值是多少。
     

    Input

    第一行,n,花盆的数量
    第二行,n个数,表示对于每盆花的喜好值。
    第三行:m, 改动的次数
    以下m行,每行两个数ki 和di 。

    Output

    M行,每一行对应一个更改,表示连续的最大喜好值,且不能整圈都选。(注意:是在圈上找)
     

    Sample Input

    5
    3 -2 1 2 -5
    4
    2 -2
    5 -5
    2 -4
    5 -1
    

    Sample Output

    4
    4
    3
    5
    
     

    Data Constraint

    这是一道爽题,子段和问题一直都是拿dp写的,今天才知道还能用线段树。

    维护以下内容:

    1. 最大前缀和
    2. 最大后缀和
    3. 最大子段和
    4. 最小前缀和
    5. 最小后缀和
    6. 最小子段和
    7. 区间和

    (真是毒瘤)

    但是更新很简单,比如最大前缀和就是max(左子树的最大区间和+右子树的最大前缀和,左子树的最大前缀和),其他的类似。

    答案就是max(最大子段和,区间和-最小子段和)。

     1 #include<bits/stdc++.h>
     2 #define f(i,a,b) for(int i=a;i<=b;i++)
     3 #define as a[o].sum
     4 #define abp a[o].big_pre_sum
     5 #define abl a[o].big_las_sum
     6 #define asp a[o].small_pre_sum
     7 #define asl a[o].small_las_sum
     8 #define bs a[o].big_sum;
     9 #define ss a[o].small_sum;
    10 using namespace std;
    11 typedef long long ll;
    12 const ll N=2e5+10;
    13 ll idx[N],pre[N],las[N];
    14 ll n,m,maxans;
    15 struct tree{
    16     ll sum;
    17     ll big_pre_sum;
    18     ll big_las_sum;
    19     ll small_pre_sum;
    20     ll small_las_sum;
    21     ll big_sum;
    22     ll small_sum;
    23 }a[N<<2];
    24 ll ls(ll o){return o<<1;}
    25 ll rs(ll o){return o<<1|1;}
    26 void pushup(ll o){
    27     as=a[ls(o)].sum+a[rs(o)].sum;
    28     abp=max(a[ls(o)].sum+a[rs(o)].big_pre_sum,a[ls(o)].big_pre_sum);
    29     asp=min(a[ls(o)].sum+a[rs(o)].small_pre_sum,a[ls(o)].small_pre_sum);
    30     abl=max(a[ls(o)].big_las_sum+a[rs(o)].sum,a[rs(o)].big_las_sum);
    31     asl=min(a[ls(o)].small_las_sum+a[rs(o)].sum,a[rs(o)].small_las_sum);
    32     a[o].big_sum=max(max(a[ls(o)].big_sum,a[rs(o)].big_sum),a[ls(o)].big_las_sum+a[rs(o)].big_pre_sum);
    33     a[o].small_sum=min(min(a[ls(o)].small_sum,a[rs(o)].small_sum),a[ls(o)].small_las_sum+a[rs(o)].small_pre_sum);
    34 }
    35 void build(ll o,ll l,ll r){
    36     if(l==r){
    37         as=abp=asp=abl=asl=a[o].big_sum=a[o].small_sum=idx[l];
    38         return;
    39     }
    40     ll mid=(l+r)>>1;
    41     build(ls(o),l,mid);
    42     build(rs(o),mid+1,r);
    43     pushup(o);
    44 }
    45 void change(ll o,ll l,ll r,ll x,ll y){
    46     if(l>x||r<x) return;
    47     if(l==r&&l==x){
    48         as=abp=asp=abl=asl=a[o].big_sum=a[o].small_sum=y;
    49         return;
    50     }
    51     ll mid=(l+r)>>1;
    52     if(x<=mid) change(ls(o),l,mid,x,y);
    53     else change(rs(o),mid+1,r,x,y);
    54     pushup(o);
    55 }
    56 //tree query(ll o,ll l,ll r,ll x,ll y){
    57 //    if(l>=x&&r<=y){
    58 //        return a[o];
    59 //    }
    60 //    ll mid=(l+r)>>1;
    61 //    if(y<=mid) return query(ls(o),l,mid,x,y);
    62 //    if(x>mid) return query(rs(o),mid+1,r,x,y);
    63 //    else{
    64 //        tree ans,l_,r_;
    65 //        l_=query(ls(o),l,mid,x,y),r_=query(rs(o),mid+1,r,x,y);
    66 //        ans.sum=l_.sum+r_.sum;
    67 //        ans.big_pre_sum=max(l_.big_pre_sum,l_.sum+r_.big_pre_sum);
    68 //        ans.big_las_sum=max(r_.big_las_sum,l_.big_las_sum+r_.sum);
    69 //        ans.small_las_sum=min(r_.small_las_sum,l_.small_las_sum+r_.sum);
    70 //        ans.small_pre_sum=min(l_.small_pre_sum,l_.sum+r_.small_pre_sum);
    71 //        ans.big_sum=max(max(l_.big_sum,r_.big_sum),l_.big_las_sum+r_.big_pre_sum);
    72 //        ans.small_sum=min(min(l_.small_sum,r_.small_sum),l_.small_las_sum+r_.small_pre_sum);
    73 //        return ans;
    74 //    }
    75 //}//------------------------------------------------------------------------后来才发现不用打这个
    76 int main(){
    77 //    freopen("data.in","r",stdin);
    78     scanf("%lld",&n);
    79     f(i,1,n) scanf("%lld",&idx[i]);
    80     build(1,1,n);
    81     scanf("%lld",&m);
    82     ll akai,hatto;
    83     f(i,1,m){
    84         scanf("%lld%lld",&akai,&hatto);//乱入一个心心
    85         change(1,1,n,akai,hatto);
    86         tree tmp=a[1];
    87         maxans=max(tmp.big_sum,tmp.sum-tmp.small_sum);
    88         printf("%lld\n",maxans);
    89     }
    90     return 0;
    91 }

    Description

    有三支队伍,分别是A,B,C。有n个游戏节目,玩第i个游戏,队伍A可以得到的分数是A[i],队伍B可以得到的分数是B[i],队伍C可以得到的分数是C[i]。由于时间有限,可能不是每个节目都能玩,于是节目主持人决定要从n个游戏节目里面挑选至少k个节目出来(被选中的节目不分次序),使得队伍A成为赢家。队伍A能成为赢家的条件是队伍A的总得分要比队伍B的总得分要高,同时也要比队伍C的总得分要高。节目主持人有多少种不同的选取方案?
     

    Input

    第一行,两个整数n和k。 

    第二行,  n个整数,分别是A[1]、A[2]、A[3]...A[n]。

    第三行,  n个整数,分别是B[1]、B[2]、B[3]...B[n]。

    第四行,  n个整数,分别是C[1]、C[2]、C[3]...C[n]。

    Output

    一个整数,表示不同的选取方案数量。
     

    Sample Input

    3 2
    1 1 2
    1 1 1
    1 1 1

    Sample Output

    3
    【样例解释】
        方案一:选取节目1和节目3。
        方案二:选取节目2和节目3。
        方案三:选取节目1、节目2、节目3。
     

    Data Constraint

    对于40%数据,2 <= n <= 20。

    对于100%数据,2 <= n <= 34,  1 <= k <= min(n,7),  1 <=A[i], B[i], C[i]<= 10^9。

    这道题,40%可以考虑dfs+剪枝,or状压dp

    对于100%,使用折半搜索与CDQ分治。

      在计算机科学中,折半搜索(英语:half-interval search),也称二分搜索(英语:binary search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。                                               ——百度百科

      1.观察数据,n<=34,使用状压dp和常规搜索显然会T飞,那么我们将搜索内容分成两半,每边最多17个数,分别搜索统计答案。

      2.我们用一个二元组表示搜索情况,发现,是不是很像一个二维偏序问题?

      3.对34的求完后,我们处理k的部分,可以通过枚举求出<=k时的答案,因此最终答案就是ans[n]-ans[k]。

      4.程序未完成,请勿搬运。

     1 #include<bits/stdc++.h>
     2 //#pragma GCC optimize(3)
     3 using namespace std;
     4 const int inf=1e9;
     5 #define f(i,a,b) for(int i=a;i<=b;i++)
     6 const int N=40;
     7 const int M=2e5+10;
     8 int sum[1<<8];
     9 int n,cnt,root,k,ans2;
    10 struct point{
    11     int a,b,c;
    12 }p[M];
    13 bool cmp(point t1,point t2){
    14     return t1.a==t2.a?t1.b<t2.b:t1.a<t2.a;
    15 }
    16 bool cmp2(point t1,point t2){
    17     return t1.b==t2.b?t1.a<t2.a:t1.b<t2.b;
    18 }
    19 struct peo{
    20     int a,b,c;
    21 }e[N];
    22 void dfs1(int st,int nd,int sum1,int sum2,int sum3){
    23     if(st>nd){
    24         p[++cnt].a=sum2-sum1;
    25         p[cnt].b=sum3-sum1;
    26         p[cnt].c=0;
    27         return;
    28     }
    29     dfs1(st+1,nd,sum1+e[st].a,sum2+e[st].b,sum3+e[st].c);
    30     dfs1(st+1,nd,sum1,sum2,sum3);
    31 }
    32 void dfs2(int st,int nd,int sum1,int sum2,int sum3){
    33     if(st>nd){
    34         p[++cnt].a=sum1-sum2;
    35         p[cnt].b=sum1-sum3;
    36         p[cnt].c=1;
    37         return;
    38     }
    39     dfs2(st+1,nd,sum1+e[st].a,sum2+e[st].b,sum3+e[st].c);
    40     dfs2(st+1,nd,sum1,sum2,sum3);
    41 }
    42 void dfs3(int x,int num,int sum1,int sum2){
    43     if(num>=k) return;
    44     if(x>n){
    45         if(sum1>0&&sum2>0) ans2++;
    46         return;
    47     }
    48     dfs3(x+1,num+1,sum1+e[x].a-e[x].b,sum2+e[x].a-e[x].c);
    49     dfs3(x+1,num,sum1,sum2);
    50 }
    51 struct array{
    52     int a[M],kk;
    53     int lb(int x){return x&-x;}
    54     int query(int x){int ans=0;for(;x;x-=lb(x))ans+=a[x];return ans;}
    55     void add(int x,int y){for(;x<=kk;x+=lb(x))a[x]+=y;}
    56 }pp,qq;
    57 int main(){
    58 //    freopen("show.in","r",stdin);
    59 //    freopen("show.out","w",stdout);
    60     scanf("%d%d",&n,&k);
    61     f(i,1,n) scanf("%d",&e[i].a);
    62     f(i,1,n) scanf("%d",&e[i].b);
    63     f(i,1,n) scanf("%d",&e[i].c);
    64     int mid=(1+n)>>1;
    65     dfs1(1,mid,0,0,0);
    66     dfs2(mid+1,n,0,0,0);
    67     sort(p+1,p+cnt+1,cmp2);
    68     int nn=-inf,cc=0,ans=0;
    69     f(i,1,cnt){
    70         if(p[i].b>nn){
    71             p[i].b=++cc;
    72             nn=p[i].b;
    73         }
    74         else p[i].b=nn;
    75     }
    76     pp.kk=cnt;
    77     sort(p+1,p+cnt+1,cmp);
    78     f(i,1,cnt){
    79         if(!p[i].c) pp.add(p[i].b,1);
    80     }
    81     f(i,1,cnt) if(p[i].c) ans+=pp.a[i];
    82 //    f(i,1,cnt) printf("%d %d %d\n",p[i].a,p[i].b,p[i].c);
    83     dfs3(1,0,0,0);
    84     printf("%d",ans-ans2);
    85     return 0;
    86 }

    调整心态。

    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    JPA常见坑
    IDEA的快捷键使用
    java注解
    @ResponseBody注解之返回json
    mybatis坑之Integer值为null
    Java后端之SQL语句
    SSM项目配置swaggerUI
    mybatis入门案例2
    mybatis入门案例
    部署本地服务器的前端及后端
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11348933.html
Copyright © 2011-2022 走看看