Codeforces Round #299 (Div. 1) 解题报告 (AB)

来源:互联网 发布:c语言经典第五版pdf 编辑:程序博客网 时间:2024/06/05 21:35

A Tavas and Karafs

        这题难读得很,英语硬伤了。。可以理解为一排高度为等差数列的柱子,给一些询问,对每个询问,每次能砍掉m根柱子1个单位的高度,砍t次,需要回答能从l开始连续砍光几根。

        思路是二分。因为肯定砍不到高度大于t的柱子,所以先找出高度不大于t的右边界,拿来和l二分。二分时比较的是这些柱子的总高度和能砍的总高度。

#include <bits/stdc++.h>      using namespace std;  #define ll long longll A,B,n;ll calc(ll l,ll r){ll re= (A+(l-1)*B + A+(r-1)*B)*(r-l+1)/2;return re;}int main(){cin>>A>>B>>n;ll l,t,m;for(int i=1;i<=n;i++){scanf("%I64d%I64d%I64d",&l,&t,&m);ll maxR=(t-A)/B+1;ll tot = t*m;if(maxR<l){printf("-1\n");}else{ll curl=l;ll curr=maxR;ll mid=curr;ll ans=curr;while(curl<=curr){mid=(curl+curr)/2;if(calc(l,mid)<=tot){curl=mid+1;ans=mid;}else{curr=mid-1;}}printf("%I64d\n",ans);}}return 0;}

B Tavas and Malekas

        原串为s,模式串p,全部都由小写英文字母组成,你知道一些肯定匹配的位置,计算s有多少种存在的可能。

        其实这题就是KMP,在串s中,把那些匹配的p填进去,然后根据空出来的位置计算就好。填进去的时候,如果完全暴力,肯定会超时,这就需要用KMP来优化,并检测冲突,如果冲突了,答案就是0,否则就是26的空槽数次幂。

#include <bits/stdc++.h>      using namespace std;  #define ll long longconst ll mod = 1e9+7;char p[1000010];int y[1000010];int _next[1000010];int n,m;bool s[1000010];int lenp;void find_next(){int k=0;lenp=strlen(p+1);for(int i=2;i<=lenp;i++){while(p[i]!=p[k+1]){k=_next[k];if(k==0)break;}if(p[i]==p[k+1])k++;_next[i]=k;}}int main(){cin>>n>>m;scanf("%s",p+1);find_next();for(int i=1;i<=m;i++){scanf("%d",&y[i]);}if(m){for(int i=y[1];i<y[1]+lenp;i++){s[i]=1;}}for(int i=2;i<=m;i++){if(y[i]-y[i-1] < lenp ){int target=lenp-(y[i]-y[i-1]);bool ok=0;int cur=lenp;while(1){cur=_next[cur];if(cur==0)break;if(cur==target){ok=1;break;}}if(ok==1){for(int j=y[i-1]+lenp;j<y[i]+lenp;j++){s[j]=1;}}else{printf("0\n");return 0;}}else{for(int j=y[i];j<y[i]+lenp;j++){s[j]=1;}}}ll ans=1;for(int i=1;i<=n;i++){if(!s[i]){ans*=26;ans%=mod;}}cout<<ans<<endl;return 0;}



0 0
原创粉丝点击