线段树模板题
线段树的题目。向上更新。
题意:有N个数[ 1,2,3,,,,,n ],取K个数,每次去第i小的数。
思路:建立一个线段树,树节点记录的是节点所表示的区间内剩余数的个数(初始化时叶子节点的值都为1,然后向上传递)。取数时,先找到第i小的数的叶子,值修改为1,然后向上传递。
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
struct point
{
int x,y;
int sum;
}a[20000000];
void tree(int t,int x,int y)
{
a[t].x=x;
a[t].y=y;
if(x==y)
{
a[t].sum=1;
return ;
}
int temp=2*t;
int mid=(x+y)/2;
tree(temp,x,mid);
tree(temp+1,mid+1,y);
a[t].sum=a[temp].sum+a[temp+1].sum;
}
int find(int t,int tot)
{
int ans;
if(a[t].x==a[t].y)
{
a[t].sum=0;
return a[t].x;
}
int temp=2*t;
if(tot<=a[temp].sum)
ans=find(temp,tot);
else
ans=find(temp+1,tot-a[temp].sum);
a[t].sum=a[temp].sum+a[temp+1].sum;
return ans;
}
int main()
{
int m,n,i,j=1,k,h;
__int64 ans;
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&n,&m);
tree(1,1,n);
ans=0;
for(i=0;i<m;i++)
{
scanf("%d",&h);
ans+=find(1,h);
}
printf("Case %d: %I64d\n",j++,ans);
}
return 0;
}