给你一个N,K;然后又有K个数i;表示从1,2,3…N个数 经过K次操作,每次操作是去掉第i小的数。求所有去掉数的之和;
#include
const int MAXN=262144;
int tree[MAXN<<1];
int pos;
void build(int l,int r,int rt)
{
tree[rt]=r-l+1;//表示节点含有的数据个数
if(r==l)
return ;
int m=(r+l)/2;
build(l,m,rt*2);
build(m+1,r,rt*2+1);
}
void update(int p,int l,int r,int rt)
{
tree[rt]--;//更新节点的数的个数
if(r==l)
{
pos=l;//此时的pos代表第几个最小值
return ;
}
int m=(r+l)/2;
if(p<=tree[rt*2])//搜索所需改变的节点
update(p,l,m,rt*2);
else
{
p-=tree[rt*2];
update(p,m+1,r,rt*2+1);
}
}
int main()
{
int t,k,n,ks,tn=1;
__int64 sum;
scanf("%d",&t);
while(t--)
{
sum=0;
scanf("%d%d",&n,&k);
build(1,n,1);
for(int i=0;i
{
scanf("%d",&ks);
update(ks,1,n,1);
sum+=pos;
}
printf("Case %d: %I64d\n",tn++,sum);
}
return 0;
}
////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
#define N 300000
#define M 2000100
#define inf64 0x7ffffff
#define inf 0x7ffffff
#define ll __int64
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Mid(x,y) ((x+y)>>1)
using namespace std;
inline ll Min(ll a,ll b){return a>b?b:a;}
inline ll Max(ll a,ll b){return a>b?a:b;}
ll len,maxdeep,Query;
struct node{
ll l,r;
ll sum;
}tree[N*8];
void build(ll l, ll r, ll id){
tree[id].l = l; tree[id].r = r;
if(l==r)
{tree[id].sum=1;return ;}
ll mid = Mid(l,r);
build(l,mid,L(id)); build(mid+1,r,R(id));
tree[id].sum = tree[L(id)].sum + tree[R(id)].sum;
}
ll ans;
void query(ll pos, ll id){ //单点询问 sum
if(tree[id].l == tree[id].r){
tree[id].sum = 0;
ans+=tree[id].l ;
return ;
}
if(pos> tree[L(id)].sum) query(pos-tree[L(id)].sum,R(id));
if(pos<=tree[L(id)].sum) query(pos,L(id));
tree[id].sum = tree[L(id)].sum + tree[R(id)].sum;
}
int main(){
ll n,a,K,i;
int T,Cas=1;scanf("%d",&T);
while(T--){
scanf("%I64d %I64d",&n,&K);
build( 1, n, 1);
ans=0;
while(K--){
scanf("%I64d",&a);
query(a,1);
}
printf("Case %d: %I64d\n",Cas++,ans);
}
return 0;
}
**************************************************************************
struct Node
{
int left,right;//左右边界
int min,max;//该区间内的最小值,最大值
};
Node node[N*3];
int a[N];//a[i]记录第i个位置上的数字
void createTree(int L,int R,int id)
{
node[id].left = L;
node[id].right = R;
//叶子节点
if(node[id].left==node[id].right)
{
node[id].min = a[L];
node[id].max = a[L];
return;
}
int mid = (node[id].left+node[id].right)>>1;
//左子树
createTree(L,mid,2*id);
//右子树
createTree(mid+1,R,2*id+1);
node[id].min = Min(node[2*id].min,node[2*id+1].min);
node[id].max = Max(node[2*id].max,node[2*id+1].max);
}
int search(int L,int R,int id, int (*function)(int,int))
{
if(node[id].left>=L&&node[id].right<=R)
return function(node[id].min,node[id].max);
int mid = (node[id].left+node[id].right)>>1;
if(R<=mid)//在左子树
return search(L,R,2*id,function);
if(L>mid)//位于右子树
return search(L,R,2*id+1,function);
//分别位于左右子树
return function(search(L,mid,2*id,function),search(mid+1,R,2*id+1,function));
}
int main()
{
int i,n,k;
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
createTree(1,n,1);
int last = n-k+1;
for(i=1;i
printf("%d ", search(i,i+k-1,1,Min));
printf("%d\n",search(i,i+k-1,1,Min));
for(i=1;i
printf("%d ",search(i,i+k-1,1,Max));
printf("%d\n",search(i,i+k-1,1,Max));
return 0;
}