逃避现实,是一种短暂的解脱。
10/0/0/0
第一题题目有误,略过。
1536. seek (Standard IO)
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet这题让我捡起了许久没动的字符串算法。
没啥好说的,就比较哈希值即可。
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 }
1537. pot (Standard IO)
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
这是一道爽题,子段和问题一直都是拿dp写的,今天才知道还能用线段树。
维护以下内容:
- 最大前缀和
- 最大后缀和
- 最大子段和
- 最小前缀和
- 最小后缀和
- 最小子段和
- 区间和
(真是毒瘤)
但是更新很简单,比如最大前缀和就是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 }
3512. 游戏节目(show)
(File IO): input:show.in output:show.out
Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits
Goto ProblemSet这道题,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 }
调整心态。