LightOJ 1097 - Lucky Number(线段树)
做了好多天的线段树基础题目,对线段树有了个大体的了解,上个代码,仅此纪念一下。
/*天王盖地虎,宝塔镇河妖,如来庇佑,佛祖让道,过过过!!*/ #include<iostream> #include<string> #include <cstdio> #include<iomanip> #include<cstring> #include<algorithm> #define maxn 820000 #define MAX 1429431 using namespace std; struct node { int l; int r; int val; int sum; }; int x[200004]; node t[maxn<<2]; void pushup(int now) { t[now].sum=t[2*now].sum+t[2*now+1].sum; } void build(int n,int l,int r) { t[n].l=l; t[n].r=r; if (l==r) { t[n].val=l*2-1; t[n].sum=1; return ; } int mid=(l+r)>>1; build(2*n,l,mid); build(2*n+1,mid+1,r); pushup(n); } void update(int now,int pos) { t[now].sum--; if (t[now].l==t[now].r) { //cout<<t[now].l<<endl; return ; } if (pos<=t[2*now].sum) { update(2*now,pos); } else { update(2*now+1,pos-t[2*now].sum); } } int query(int now,int pos) { if (t[now].l==t[now].r) { return t[now].val; } if (pos<=t[2*now].sum) { return query(2*now,pos); } else { return query(2*now+1,pos-t[2*now].sum); } } int main() { int T,n,m; int count1=2; x[1]=1; int num=MAX/2+1; build(1,1,num); for (int number=2; number<=100000; number++) { m=query(1,number); x[count1]=m; count1++; for(int j=1;; j++) { if (m*j>=(num))break; update(1,m*j-(j-1)); } } cin>>T; for (int i=1;i<=T;i++) { scanf("%d",&n); printf("Case %d: ",i); printf("%d\n",x[n]); } return 0; }