1. 程式人生 > >洛谷 P3332 [ZJOI2013]K大數查詢 || bzoj3110

洛谷 P3332 [ZJOI2013]K大數查詢 || bzoj3110

AI #define k大數查詢 printf emc ret eof else space

用樹套樹就很麻煩,用整體二分就成了裸題。。。。

錯誤:

1.嘗試線段樹套平衡樹,碼農,而且n*log^3(n)慢慢卡反正我覺得卡不過去

2.線段樹pushdown寫錯。。。加法tag對於區間和的更新應該要乘上區間長度的

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 using namespace std;
  5 typedef long long LL;
  6 struct Q
  7 {
  8     LL type,a,b,c,num;
9 }q[50100],qt1[50100],qt2[50100]; 10 LL ans[50100],qnum; 11 LL n,m; 12 namespace SegT 13 { 14 #define mid (l+((r-l)>>1)) 15 #define lc (num<<1) 16 #define rc (num<<1|1) 17 LL dat[200100],addv[200100]; 18 LL L,R,x; 19 void pd(LL l,LL r,LL num) 20 { 21 if(addv[num]) 22 {
23 dat[lc]+=(mid-l+1)*addv[num];addv[lc]+=addv[num]; 24 dat[rc]+=(r-mid)*addv[num];addv[rc]+=addv[num]; 25 addv[num]=0; 26 } 27 } 28 void _addx(LL l,LL r,LL num) 29 { 30 if(L<=l&&r<=R) {dat[num]+=(r-l+1)*x;addv[num]+=x;return;} 31 pd(l,r,num);
32 if(L<=mid) _addx(l,mid,lc); 33 if(mid<R) _addx(mid+1,r,rc); 34 dat[num]=dat[lc]+dat[rc]; 35 } 36 LL _query(LL l,LL r,LL num) 37 { 38 if(L<=l&&r<=R) return dat[num]; 39 pd(l,r,num);LL ans=0; 40 if(L<=mid) ans+=_query(l,mid,lc); 41 if(mid<R) ans+=_query(mid+1,r,rc); 42 return ans; 43 } 44 void addx(LL l,LL r,LL d) 45 { 46 L=l;R=r;x=d;_addx(1,n,1); 47 } 48 LL query(LL l,LL r) 49 { 50 L=l;R=r;return _query(1,n,1); 51 } 52 #undef mid 53 #undef lc 54 #undef rc 55 } 56 void solve(LL lp,LL rp,LL l,LL r) 57 { 58 if(lp>rp) return; 59 LL i; 60 if(l==r) 61 { 62 for(i=lp;i<=rp;i++) 63 if(q[i].type==2) 64 ans[q[i].num]=l; 65 return; 66 } 67 LL mid=l+((r-l)>>1),tlen1=0,tlen2=0,t; 68 for(i=lp;i<=rp;i++) 69 { 70 if(q[i].type==1) 71 { 72 if(q[i].c>mid) 73 { 74 SegT::addx(q[i].a,q[i].b,1); 75 qt1[++tlen1]=q[i]; 76 } 77 else 78 qt2[++tlen2]=q[i]; 79 } 80 else 81 { 82 t=SegT::query(q[i].a,q[i].b); 83 if(t>=q[i].c) 84 qt1[++tlen1]=q[i]; 85 else 86 qt2[++tlen2]=q[i],qt2[tlen2].c-=t; 87 } 88 } 89 for(i=lp;i<=rp;i++) 90 if(q[i].type==1&&q[i].c>mid) 91 SegT::addx(q[i].a,q[i].b,-1); 92 memcpy(q+lp,qt1+1,sizeof(Q)*tlen1); 93 memcpy(q+lp+tlen1,qt2+1,sizeof(Q)*tlen2); 94 solve(lp,lp+tlen1-1,mid+1,r); 95 solve(lp+tlen1,rp,l,mid); 96 } 97 int main() 98 { 99 LL i; 100 scanf("%lld%lld",&n,&m); 101 for(i=1;i<=m;i++) 102 { 103 scanf("%lld%lld%lld%lld",&q[i].type,&q[i].a,&q[i].b,&q[i].c); 104 if(q[i].type==2) q[i].num=++qnum; 105 } 106 solve(1,m,-50000,50000); 107 for(i=1;i<=qnum;i++) printf("%lld\n",ans[i]); 108 return 0; 109 }

洛谷 P3332 [ZJOI2013]K大數查詢 || bzoj3110