做了好多天的线段树基础题目,对线段树有了个大体的了解,上个代码,仅此纪念一下。
/*天王盖地虎,宝塔镇河妖,如来庇佑,佛祖让道,过过过!!*/
#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;
}