8.11模拟赛

B组

T1.

模拟一下就能发现,从小到大排序后,就是在一个长度为n的序列上插入到第k个空位,因为要字典序小,尽量往左插入,所以k=min(y+1,n-i-y+1)

这个可以用线段树二分维护一下!

#include<algorithm>
#include<iostream>
#include<cstdio>

using namespace std;

inline int rd(){
    int ret=0,f=1;char c;
    while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    return ret*f;
}

const int MAXN=100005;

struct Node{
    int x,y;
    bool operator<(const Node &rhs)const {
        return x<rhs.x;
    }
}a[MAXN];

int n;
int lef[MAXN];

#define ls (cur<<1)
#define rs (cur<<1|1)
#define mid (l+r>>1)
int val[MAXN<<2],elm[MAXN<<2];
void pushup(int cur){
    val[cur]=val[ls]+val[rs];
}
void build(int cur,int l,int r){
    if(l==r){val[cur]=1;lef[l]=cur;return;}
    build(ls,l,mid);build(rs,mid+1,r);
    pushup(cur);
}
void update(int cur,int l,int r,int w,int id){
    if(l==r){val[cur]=0;elm[cur]=id;return;}
    if(val[ls]>=w) update(ls,l,mid,w,id);
    else update(rs,mid+1,r,w-val[ls],id);
    pushup(cur);
}
int main(){
    freopen("queue.in","r",stdin);
    freopen("queue.out","w",stdout);
    n=rd();
    build(1,1,n);
    for(int i=1;i<=n;i++){
        a[i].x=rd();a[i].y=rd();
    }
    sort(a+1,a+1+n);
    for(int i=n;i>=1;i--){
        if(a[i].y>=n-i+1) return puts("impossible"),0;
    }
    for(int i=1;i<=n;i++){
        update(1,1,n,min(a[i].y+1,n-i-a[i].y+1),a[i].x);
    }
    for(int i=1;i<=n;i++) cout<<elm[lef[i]]<<" ";
    return 0;
}
View Code

 T2.prime 质数

在筛素数的时候顺便筛出i*j,其中i和j为质数

前缀和乱搞就行了

一开始想了nln(n)的做法,蠢飞了

#include<algorithm>
#include<iostream>
#include<cstdio>

using namespace std;

inline int rd(){
    int ret=0,f=1;char c;
    while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    return ret*f;
}

const int MAXN=10000005;

bool isx[MAXN],se[MAXN];
int prime[MAXN],tot;
int sum[MAXN];
void mkprime(int x){
    isx[1]=1;
    for(int i=2;i<=x;i++){
        if(!isx[i]){
            prime[++tot]=i;
            for(int j=1;j<=tot&&prime[j]*i<=x;j++){
                int v=prime[j];
                isx[i*v]=1;
                se[i*v]=1;
                if(i%v==0) break;
            }
        }else{
            for(int j=1;j<=tot&&prime[j]*i<=x;j++){
                int v=prime[j];
                isx[i*v]=1;
                if(i%v==0) break;
            }
        }
    }
    for(int i=1;i<=10000000;i++){
        sum[i]=sum[i-1]+(!isx[i])+se[i];
    }
}

int q;

int main(){
    freopen("prime.in","r",stdin);
    freopen("prime.out","w",stdout);
    mkprime(10000000);
    q=rd();
    int x,y;
    for(int i=1;i<=q;i++){
        x=rd();y=rd();
        printf("%d\n",sum[y]-sum[x-1]);
    }
    return 0;
}
    
            

            
View Code

 

猜你喜欢

转载自www.cnblogs.com/ghostcai/p/9460212.html