P1 签到题不多说..
#include <iostream> #include <cstdio> using namespace std; int n,m,p,q; int a[300]; int ans; int main() { cin>>n>>m; for (int i=1; i<=n; i++) cin>>a[i]; ans=0; for (int i=1; i<n; i++) if (a[i]-a[i+1]-m>ans) ans=a[i]-a[i+1]-m; cout<<ans<<endl; return 0; }
P2,给一个字符串,问有多少个二元组l,r符合substring(l,r)至少含有一个"bear"。暴力匹配bear,每次统计出当前匹配头到上一次匹配头之间的字母数x,当前匹配尾到字符串尾的字母数y,ans+=x*y,匹配完所有情况ans就是要的答案。
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> using namespace std; typedef long long ll; int n,m,p,q; int ans; char s[7000]; int main() { // freopen("in.txt","r",stdin); gets(s); int len=strlen(s); int last=0; for (int i=0; i+3<len; i++) { if (s[i]=='b' && s[i+1]=='e' && s[i+2]=='a' && s[i+3]=='r') { ans+=(i-last+1)*(len-i-3); last=i+1; } } cout<<ans<<endl; return 0; }
P3,给n个数,m组查询,每次查询一个区间l,r,对l,r之间的每个素数,统计n个数中有多少个数是其倍数,并求和..这题我是把n个数全部做了一次分解质因数,每分解出一个素数k就把对应cot[k]++表示其出现的次数+1,查询的时候统计一下l,r之间的素数的cot[i]的和即可..具体实现看代码吧...不过这应该不是正解...cf上跑了1965ms,还是很悬的.....结束后看到一种做法,直接记录每个数出现的次数,然后质数加倍去统计就好..这么做三四百毫秒好像就可以过......
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; typedef long long ll; const int maxn=1e7+11; bool ok[maxn]; int prime[700000+100]; ll cot[700000+100]; int n,m,k; int cnt; int dv[700000]; void ss() { memset(ok,true,sizeof ok); ok[2]=true; ok[1]=false; ok[0]=false; for (int i=2; i<maxn; i++) { if (ok[i]) { for (int j=i+i; j<maxn; j+=i) if (ok[j]) ok[j]=false; } } cnt=0; for (int i=2; i<maxn; i++) if (ok[i]) { prime[cnt++]=i; } // for (int i=0; i<cnt; i++) // cout<<prime[i]<<"\n"; // cout<<endl; } int search(int v) { int m; int l=0; int r=cnt; while (l<r) { m=(l+r)>>1; if (prime[m]<v) l=m+1; else r=m; } return l; } void dvd(int num) { dv[0]=0; int xx=num; if (!ok[num]) { int y=0,kk=0,tt=1; while(xx) { if (xx%prime[y]==0) { // dv[++dv[0]]=prime[y]; cot[y]++; while (xx%prime[y]==0) xx=xx/prime[y]; } else { y++; } if (xx==1) break; if (ok[xx]) { // dv[++dv[0]]=xx; int ps=search(xx); cot[ps]++; break; } } } else { int ps=search(num); cot[ps]++; } // for (int i=1; i<dv[0]; i++) // cout<<dv[i]<<"*"; // cout<<dv[dv[0]]<<endl; } struct node { int l,r,id; ll ans; bool operator<(const node& b)const { if (l==b.l) return r<b.r; return l<b.l; } }qy[50550]; int main() { // freopen("in.txt","r",stdin); ss(); memset(cot,0,sizeof cot); scanf("%d",&n); for (int i=1; i<=n; i++) { scanf("%d",&k); dvd(k); } for (int i=0; i<cnt; i++) cot[i]+=cot[i-1]; int x,y; ll ans=0; ll ss1,ss2; scanf("%d",&m); for (int i=1; i<=m; i++) { ans=0; scanf("%d%d",&x,&y); int s1=search(x); int s2=search(y); bool c1=false; if (prime[s1]!=x) s1--,c1=true; if (prime[s2]!=y) s2--; if (s1>0) { if (!c1) ans+=cot[s2]-cot[s1-1]; else ans+=cot[s2]-cot[s1]; } else ans+=cot[s2]; printf("%I64d\n",ans); } return 0; }