hdu5412

这道题是待修改的求区间k小值,本来是想用树状数组+主席树,结果超时,用整体二分,结果因为数组开小了,一直wr,(再一次警告自己:wr有可能是数组开小了,但是小的又不是很多时,有可能是wr,而不是re发火

代码参考:http://blog.csdn.net/hdu2014/article/details/47834431

(感觉草莓味的软糖比草莓好吃!)

2015.8.29:

回想了一遍整体二分的过程,看到这里对自己的警告,只能说,亲爱的自己,没过几天,又犯了这个毛病,而且找了好久才发现,有待提高骂人

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define N 100010

int ty[3*N],qr[3*N],ql[3*N],qk[3*N],ans[3*N];
int num[N];
int newid[2*N];//因为开小了,所以一直wr
int L[4*N],R[4*N];
int c[N];
int mark[N];
vector<int> dp[4*N];
//vector<int> v;
int nid;
int n;
int nowloca;

void lisanhua(){
    sort(newid,newid+nid);
    nid=unique(newid,newid+nid)-newid;
    /*sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());*/
}

int numhash(int x){
    return lower_bound(newid,newid+nid,x)-newid+1;
    //return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}

int lowbit(int x){
    return ((~x)+1)&x;
}

void change(int x,int cou){
    while(x<=n){
        //printf("%d ",x);
        if(mark[x]!=nowloca){
            mark[x]=nowloca;
            c[x]=0;
        }
        c[x]+=cou;
        x=x+lowbit(x);
    }
}

int sum(int x){
    int ans=0;

    while(x>0){
        if(mark[x]==nowloca){
           ans+=c[x];
        }
        x=x-lowbit(x);
    }

    return ans;
}

int main(){
    int q;
    int qid;
    int nextloca;

    while(scanf("%d",&n)!=EOF){
        qid=0;
        nid=0;
        //v.clear();
        dp[0].clear();
        for(int i=1;i<=n;i++){
            scanf("%d",&num[i]);
            newid[nid++]=num[i];
            //v.push_back(num[i]);
            ty[qid]=1;
            ql[qid]=i;
            qr[qid]=num[i];
            dp[0].push_back(qid++);
        }
        scanf("%d",&q);
        for(int i=0;i<q;i++){
            scanf("%d%d%d",&ty[qid],&ql[qid],&qr[qid]);
            if(ty[qid]==2){
                scanf("%d",&qk[qid]);
            }
            else{
                dp[0].push_back(qid++);
                ty[qid]=-1;
                ql[qid]=ql[qid-1];
                qr[qid]=num[ql[qid]];
                num[ql[qid]]=qr[qid-1];
                newid[nid++]=qr[qid-1];
                //v.push_back(qr[qid-1]);
            }
            dp[0].push_back(qid++);
        }

        /*for(int i=0;i<qid;i++){
            printf("%d %d\n",i,ql[i]);
        }*/

        lisanhua();
        for(int i=0;i<qid;i++){
            if(ty[i]!=2){
                qr[i]=numhash(qr[i]);
            }
        }

        nowloca=0;nextloca=1;
        L[0]=1;R[0]=nid/*v.size()*/;
        memset(c,0,sizeof(c));
        memset(mark,0,sizeof(mark));
        while(nowloca<nextloca){
            if(L[nowloca]==R[nowloca]){
                for(int i=0;i<dp[nowloca].size();i++){
                    int u=dp[nowloca][i];

                    if(ty[u]==2){
                        ans[u]=newid[L[nowloca]-1];
                    }
                }
            }
            else{
                int l=nextloca++;
                int r=nextloca++;
                int middle=(L[nowloca]+R[nowloca])>>1;
                L[l]=L[nowloca];
                R[l]=middle;
                L[r]=middle+1;
                R[r]=R[nowloca];
                dp[l].clear();
                dp[r].clear();

                //memset(c,0,sizeof(c));//这样会超时
                for(int i=0;i<dp[nowloca].size();i++){
                    int u=dp[nowloca][i];

                    if(ty[u]==2){
                        int cnt=sum(qr[u])-sum(ql[u]-1);
                        //printf("%d %d\n",cnt,u);
                        if(qk[u]<=cnt){
                            dp[l].push_back(u);
                        }
                        else{
                            qk[u]-=cnt;
                            dp[r].push_back(u);
                        }
                    }
                    else{
                        if(qr[u]>middle){
                            dp[r].push_back(u);
                        }
                        else{
                            //printf("%d %dha ",u,ql[u]);
                            change(ql[u],ty[u]);//调错:在change这个函数这里没有返回来了
                            dp[l].push_back(u);
                        }
                    }
                }
            }
            nowloca++;//printf("wo shi da hao ren\n");
        }

        for(int i=0;i<qid;i++){
            if(ty[i]==2){
                printf("%d\n",ans[i]);
            }
        }
    }

    return 0;
}


转载于:https://www.cnblogs.com/ahahah/p/4918209.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值