BestCoder Round #18

1001 Primes Problem

 打个10^4的素数表,枚举前两个搞一下就好了。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<map>

#include<vector>

#include<stdlib.h>

#include<algorithm>

#include<math.h>

using namespace std;

const int n = 10000;

int vis[11111];

int cnt ;

int ans[11111];

void gao()

{

    memset(vis,0,sizeof(vis));

    for(int i= 2;i<=sqrt(n);i++){

        for(int j= 2;i*j<=n;j++)

            if(!vis[i]) vis[i*j] = 1;

    }

    vis[0] = 1;vis[1] = 1;

    cnt = 0;

    for(int i = 2;i<=n;i++)

        if(!vis[i]) ans[cnt++] = i;

}



int main()

{

    gao();

    int k;

    while(cin>>k){

        int sum = 0;

        for(int i = 0;i<cnt;i++){

            if(ans[i]>=k) continue;

            for(int j=i;j<cnt;j++){

                int t = k-ans[i]-ans[j];

                if(t<=0) break;

                if(vis[t]||t<ans[j]) continue;

                else sum++;

            }

        }

        printf("%d\n",sum);

    }

    return  0;

}
1002 Math Problem
解方程啊,预测数据太水,我没加根号都能过预测,无语。
#include<iostream>

#include<cstdio>

#include<cstring>

#include<map>

#include<vector>

#include<stdlib.h>

#include<algorithm>

#include<math.h>

using namespace std;

#define eps  = 1e-7

double a,b,c,d,L,R;

double x1,x2;

int gao()

{

    double  t =  4*b*b - 12*a*c;

    if(t<0) return 0;

    else{

        x1 = (-2) * b + sqrt(t);

        x1/=6*a;

        x2 = (-2)*b - sqrt(t); x2/=6*a;

    }

    return 1;

}



double qiu(double x)

{

    double t = a*x*x*x + b*x*x + c*x +d;

    return fabs(t);

}

double qiu1(double x)

{

    double t = b*x*x + c*x+d;

    return fabs(t);

}

int main()

{

    double t1,t2;

    while(cin>>a>>b>>c>>d>>L>>R){

        t1 = qiu(L);t2 = qiu(R);

        if(a==0){

            if(b==0){

                printf("%.2lf\n",max(t1,t2));

            }

            else{

                double t4 = (-c) / (2*b);

                if(t4>=L&&t4<=R){

                double t3 = qiu1((-c)/(2*b));

                t1 = max(t1,t2);

                t1 =max(t1,t3);

                printf("%.2lf\n",t1);

                }

                else{

                    printf("%.2lf\n",max(t1,t2));

                }

            }

            continue;

        }

        if(!gao()){

            printf("%.2lf\n",max(t1,t2));

            continue;

        }

        else{

            double t3 = qiu(x1) ;double t4 = qiu(x2);

            t3 = max(t3,t4);

            t1 = max(t1,t2);

            printf("%.2lf\n",max(t1,t3));

        }

    }

    return 0;

}
1003 Bits Problem
数位dp,记录一个的到当前位满足条件的1的种类数,记录一个到当前位满足条件的数的和
因为是开区间,最后单独判断一下右端点。
#include<stdio.h>

#include<string.h>

#include<vector>

#include<iostream>

#include<map>

#include<queue>



using namespace std;



const int mod = 1e9+7;

typedef long long LL;

const int maxn = 1111;

int dp_sum[maxn][maxn];

int dp_mod[maxn][maxn];

int n;

int val[maxn];

char str[maxn];

int dfs_sum(int x,int sum,int flag)

{

    if(~dp_sum[x][sum]&&!flag) return dp_sum[x][sum];

    int bound = flag? val[x]:1;

    if(x==0){

        if(sum==0)return 1;

        else return 0;

    }

    int ans = 0 ;

    for(int i = 0 ;i<=bound;i++){

        if(i==0) ans+=dfs_sum(x-1,sum,flag&&bound==i),ans%=mod;

        else{

            if(sum>0) ans+=dfs_sum(x-1,sum-1,flag&&bound==i),ans%=mod;

        }

    }

    return flag? ans:dp_sum[x][sum] = ans;

}



LL cifang(LL a,int b)

{

    LL ans = 1;

    while(b){

        if(b&1) ans*=a,ans%=mod;

        a*=a;a%=mod; b>>=1;

    }

    return ans;

}



LL dfs_mod(int x,int sum,int flag)

{

    if(~dp_mod[x][sum]&&!flag) return dp_mod[x][sum];

    int bound = flag? val[x] : 1;

    if(x==0) return 0;

    LL ans = 0 ;

    for(int i = 0 ;i<=bound;i++){

        if(i==0){

            ans+=dfs_mod(x-1,sum,flag&&bound==i),ans%=mod;

        }

        else{

            if(sum<=0) continue;

            int t = dfs_sum(x-1,sum-1,flag&&bound == i );

            ans+=t%mod*cifang(2,x-1)%mod;

            ans+=dfs_mod(x-1,sum-1,flag&&bound==i),ans%=mod;

        }

    }

    return flag?ans:dp_mod[x][sum] = ans;

}



void gao()

{

    int len =strlen(str);

    for(int i = 0 ;i<len;i++){

        val[i+1] = str[len-i-1] - '0';

    }

    LL t = dfs_mod(len,n,1);

    int ans = 0;

    int cnt = 0;

    for(int i = len;i>=1;i--)

        if(val[i]) cnt++;

    for(int i = len;i>=1;i--){

        ans=ans*2+val[i];ans%=mod;

    }

    if(cnt==n) t-=ans;

    if(t<0) t = (t+mod) % mod;

    printf("%I64d\n",t);

}



int main()

{

    memset(dp_sum,-1,sizeof(dp_sum));

    memset(dp_mod,-1,sizeof(dp_mod));

   // system("pause");

    while(scanf("%d",&n)!=EOF){

        scanf("%s",str);

        gao();

    }

    return 0;

}
1004 K-short Problem
先离散化。
k最大为10嘛,每个节点记录从小到大记录十个数。
按x从小到大,y从小到大,h从小到大
以y轴建树
离线更新查询同时进行 ,线段树上的操作暴力搞就好。
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <map>

#include <set>

#include <bitset>

#include <queue>

#include <stack>

#include <string>

#include <iostream>

#include <cmath>

#include <climits>



using namespace std;



#define lson l,mid,rt<<1

#define rson mid+1,r,rt<<1|1

const int maxn = 66666;



vector<int> node[maxn<<2];

vector<int> gg;

int n,m;

vector<int> ans;

int val[maxn];

struct Node

{

    int x;int y;int h;int pos;

}edge[maxn],edge1[maxn];

int len;

int cmp(const Node &a,const Node &b)

{

    if(a.x!=b.x) return a.x<b.x;

    if(a.y!=b.y) return a.y<b.y;

    return a.h<b.h;

}



void gao1()

{

    gg.clear();

    for(int i = 0;i<n;i++)

        gg.push_back(edge[i].y);

    for(int i = 0;i<m;i++)

        gg.push_back(edge1[i].y);

    sort(gg.begin(),gg.end());

    gg.erase(unique(gg.begin(),gg.end()),gg.end());

    for(int i = 0;i<n;i++)

        edge[i].y = lower_bound(gg.begin(),gg.end(),edge[i].y) - gg.begin();

    for(int i =0;i<m;i++)

        edge1[i].y = lower_bound(gg.begin(),gg.end(),edge1[i].y) - gg.begin();

    len = gg.size() - 1;

}



void up(int rt)

{

    node[rt].clear();

    int a[22];int cnt = 0;

    for(int i= 0;i<node[rt<<1].size();i++){

        a[cnt++] = node[rt<<1][i];

    }

    for(int i =0;i<node[rt<<1|1].size();i++){

        a[cnt++] = node[rt<<1|1][i];

    }

    sort(a,a+cnt);

    cnt = min(cnt,10);

    for(int i =0;i<cnt;i++)

        node[rt].push_back(a[i]);

}



void build(int l,int r,int rt)

{

    node[rt].clear();

    if(l==r) return ;

    int mid=(l+r)>>1;

    build(lson);

    build(rson);

}



void update(int key,int add,int l,int r,int rt)

{

    if(l==r){

        node[rt].push_back(add);

        sort(node[rt].begin(),node[rt].end());

        return ;

    }

    int mid=(l+r)>>1;

    if(key<=mid) update(key,add,lson);

    else update(key,add,rson);

    up(rt);

}



void ask(int L,int R,int l,int r,int rt)

{

    if(L<=l&&r<=R){

        for(int i = 0 ;i<node[rt].size();i++)

            ans.push_back(node[rt][i]);

        return ;

    }

    int mid=(l+r)>>1;

    if(L<=mid) ask(L,R,lson);

    if(R>mid) ask(L,R,rson);

}



void gao(int L,int R,int k,int l,int r,int rt,int pos)

{

    ans.clear();

    ask(L,R,l,r,rt);

    if(ans.size()<k) val[pos] = -1;

    else{

        sort(ans.begin(),ans.end());

        val[pos] = ans[k-1];

    }

}

int main()

{

    while(cin>>n>>m){

        for(int i = 0 ;i<n;i++){

            scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].h);

        }

        for(int i = 0;i<m;i++){

            scanf("%d%d%d",&edge1[i].x,&edge1[i].y,&edge1[i].h);

            edge1[i].pos = i;

        }

        gao1();

        sort(edge,edge+n,cmp);

        sort(edge1,edge1+m,cmp);

        build(0,len,1);

        int cnt = 0;

        for(int i = 0;i<m;i++){

            while(1){

                if(cnt>=n) break;

                if(edge[cnt].x>edge1[i].x) break;

                update(edge[cnt].y,edge[cnt].h,0,len,1);

                cnt++;

            }

            gao(0,edge1[i].y,edge1[i].h,0,len,1,edge1[i].pos);

        }

        for(int i = 0;i<m;i++){

            printf("%d\n",val[i]);

        }

    }

    return 0;

}

 

你可能感兴趣的:(round)