F.A.Q
Hand In Hand
Online Acmers
Problem Archive
Realtime Judge Status
Authors Ranklist
 
     C/C++/Java Exams     
ACM Steps
Go to Job
Contest LiveCast
ICPC@China
Best Coder beta
VIP | STD Contests
    DIY | Web-DIY beta
Author ID 
Password 
 Register new ID

View Compilation Error

0_0_23257390_17259.cpp: In function 'int update(int, int)':
0_0_23257390_17259.cpp:32:35: error: expected '}' at end of input
     tree[tot].num=tree[root].num+1;//此时新创立的根节点的值等于上一个创立的树的根节点的值+1(因为每次只更新一个位置的值+1 因此总体也只+1    int left=1;int right=tot_num;//对上一颗树进行扫描 寻找需要更改增加的节点和无需更改的节点    while(left<right)    {        int mid=(left+right)>>1;        if(x<=mid)//如果需要更改的值在左子树        {            tree[now].right=tree[root].right;//此时新创立的节点的右子树就是此时扫描点的右子树 因为无需更改 直接将新创立节点的右子树指向扫描点的右子树 这也是主席树精华所在(个人认为) 很大程度上节约了空间            tree[now].left=++tot;//在当前的新节点上对左子树创立一个新节点 此时当前新节点已经完成 递归进入下一个新节点            root=tree[root].left;//扫描的点进行与上面同样的动作 往左扫描            now=tot;//此时的新节点变为了当前新节点的左节点 然后递归            right=mid;//二分步骤        }        else        {                                   //类比左子树            tree[now].left=tree[root].left;            tree[now].right=++tot;            root=tree[root].right;            now=tot;            left=mid+1;        }        tree[now].num=tree[root].num+1;//对于新节点 即已经判断需要更改的节点在此区间 对其值进行更新 同样只需要+1    }    return tmp;//返回之前记录的这个新创立的线段树的根节点}int query(int qleft,int qright,int k)//qleft为1~i这个线段树的根节点 qright为1~j的 (假设查询【i~j】区间)(i~j区间的线段树可表示为 线段树j-1减去线段树((i-1)-1)类比树状数组思想 而接下来的操作都是在两个线段树的相加减基础上的 之所以可以相加减 因为主席树里的线段树保证了结构相同的特点{    int left=1;int right=tot_num;    while(left<right)    {        int mid=(left+right)>>1;        if(tree[tree[qright].left].num-tree[tree[qleft].left].num>=k)//如果左子树的值大于等于 说明第k大的树在左子树中        {            qleft=tree[qleft].left;            qright=tree[qright].left;            right=mid;        }        else//否则在右子树中        {            left=mid+1;            k-=(tree[tree[qright].left].num-tree[tree[qleft].left].num);            qleft=tree[qleft].right;            qright=tree[qright].right;        }    }    return left;//对相减的线段树进行扫描寻找第k大的值 直到找到 返回的值注意不是数本身 是第k大的数的下标 之后再在已经排序的c数组里得到这个数的具体值}int main(){    int n,m;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        scanf("%d",&b[i]);        c[i]=b[i];    }    sort(c+1,c+1+n);//先排序    tot_num=unique(c+1,c+n+1)-c-1;//后去重 这里之所以不用set容器实现 因为操作运算符里“-"不允许对其地址的加减操作(差不多这么解释。。 迭代器的东西跟操作运算符不是太懂 本来写的lower_bound()-set.begin()就是会报错运算符)    t[0]=build(1,tot_num);//先是基础树(num都为0)    for(int i=1;i<=n;i++)    {        t[i]=update(t[i-1],lower_bound(c+1,c+tot_num+1,b[i])-c);//每个树在上一个树的基础上进行更新和扫描    }    while(m--)    {        int l,r,k;        scanf("%d%d%d",&l,&r,&k);        printf("%d\n",c[query(t[l-1],t[r],k)]);//最后query返回的是c数组位置的下标索引     }}
                                   ^


Hangzhou Dianzi University Online Judge 3.0
Copyright © 2005-2024 HDU ACM Team. All Rights Reserved.
Designer & Developer : Wang Rongtao LinLe GaoJie GanLu
Total 0.000000(s) query 1, Server time : 2024-10-23 11:23:16, Gzip enabled