BZOJ 3110 [ZJOI2013]K大数查询 (整体二分+线段树)

dynamic rankings这道题的思想一样

只不过是把树状数组换成线段树区间修改,求第$K$大的而不是第$K$小的

这道题还有负数,需要离散

 1 #include <vector>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define N1 50500
 6 #define M1 100500
 7 #define ll long long
 8 #define dd double
 9 #define inf 233333333
10 using namespace std;
11 
12 int gint()
13 {
14     int ret=0,fh=1;char c=getchar();
15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
17     return ret*fh;
18 }
19 ll gll()
20 {
21     ll ret=0;int fh=1; char c=getchar();
22     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
23     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
24     return ret*fh;
25 }
26 
27 struct SEG{
28 ll sum[N1<<2],tag[N1<<2];int use[N1<<2],que[N1<<2],tl;
29 void pushdown(int l,int r,int rt)
30 {
31     if(!tag[rt]) return;
32     int mid=(l+r)>>1;
33     sum[rt<<1]+=tag[rt]*(mid-l+1); tag[rt<<1]+=tag[rt];
34     sum[rt<<1|1]+=tag[rt]*(r-mid); tag[rt<<1|1]+=tag[rt];
35     if(!use[rt<<1]) use[rt<<1]=1,que[++tl]=rt<<1;
36     if(!use[rt<<1|1]) use[rt<<1|1]=1,que[++tl]=rt<<1|1;
37     tag[rt]=0;
38 }
39 void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; }
40 void update(int L,int R,int l,int r,int rt,int w)
41 {
42     if(!use[rt]) use[rt]=1,que[++tl]=rt;
43     if(L<=l&&r<=R){ sum[rt]+=(r-l+1)*w; tag[rt]+=w; return;}
44     int mid=(l+r)>>1; pushdown(l,r,rt);
45     if(L<=mid) update(L,R,l,mid,rt<<1,w);
46     if(R>mid) update(L,R,mid+1,r,rt<<1|1,w);
47     pushup(rt); 
48 }
49 ll query(int L,int R,int l,int r,int rt)
50 {
51     if(L<=l&&r<=R) return sum[rt];
52     int mid=(l+r)>>1; ll ans=0; pushdown(l,r,rt);
53     if(L<=mid) ans+=query(L,R,l,mid,rt<<1);
54     if(R>mid) ans+=query(L,R,mid+1,r,rt<<1|1);
55     return ans;
56 }
57 void clr(){ while(tl){ use[que[tl]]=0; sum[que[tl]]=0; tag[que[tl]]=0; que[tl--]=0; } }
58 }s;
59 struct node{int fl,l,r,ans,t;ll K;}a[N1],tmp[N1];
60 int n,m,ma,nn;
61 int f[N1],w[N1],use[N1];
62 
63 void alldic(int l,int r,int ql,int qr)
64 {
65     if(l>r||ql>qr) return;
66     int mid=(l+r)>>1,i,j,S=ql,E;ll sum;
67     for(i=ql;i<=qr;i++)
68     {
69         if(a[i].fl==1){
70             if(a[i].K>=mid){ s.update(a[i].l,a[i].r,1,n,1,1); use[i]=1; }
71             if(a[i].K>mid){ tmp[S++]=a[i]; }
72         }else{
73             sum=s.query(a[i].l,a[i].r,1,n,1);
74             if(sum<a[i].K){ a[i].K-=sum; }
75             else{ f[a[i].t]=w[mid]; tmp[S++]=a[i]; use[i]=1; }
76         }
77     }
78     for(i=ql,E=S;i<=qr;i++)
79     {
80         if(!use[i]){ tmp[E++]=a[i]; }
81         else{ use[i]=0; }
82     }
83     for(i=ql;i<=qr;i++) a[i]=tmp[i];
84     s.clr();
85     alldic(mid+1,r,ql,S-1); alldic(l,mid-1,S,E-1);
86 } 
87 
88 int main()
89 {
90     scanf("%d%d",&n,&m);
91     int i,j; memset(f,-1,sizeof(f));
92     for(i=1;i<=m;i++){ a[i].fl=gint(); a[i].l=gint(); a[i].r=gint(); a[i].K=gll(); a[i].t=i; if(a[i].fl==1) w[++ma]=a[i].K; }
93     sort(w+1,w+ma+1); ma=unique(w+1,w+ma+1)-(w+1); 
94     for(i=1;i<=m;i++){ if(a[i].fl==1) a[i].K=lower_bound(w+1,w+ma+1,a[i].K)-w; }
95     alldic(1,ma,1,m);
96     for(i=1;i<=m;i++) if(f[i]!=-1) printf("%d\n",f[i]);
97     return 0;
98 }

 

posted @ 2019-01-04 13:59  guapisolo  阅读(160)  评论(0编辑  收藏  举报