现在的位置: 首页 > 综合 > 正文

Codeforces round#226 div2

2014年09月05日 ⁄ 综合 ⁄ 共 2467字 ⁄ 字号 评论关闭

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;
}

抱歉!评论已关闭.