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