有点蒙

P4390 [BalkanOI2007] Mokia 摩基亚

```cpp // luogu-judger-enable-o2 // luogu-judger-enable-o2 // luogu-judger-enable-o2 #include <iostream> #include <algorithm> #include <stack> using namespace std; #define reg register typedef long long ll; const int kmaxn=160000+(10000<<2)+5; int opt,a,b,c,d,t=0; int n; bool flag=true; const int kmaxlength=2000000+500; ll tree[kmaxlength]; stack<int> s; enum KIND{ useless=0,ADD=1,REQ=2 }; ll ans[kmaxn]; struct unit{ KIND k=useless; int x,y; int inf; int a,b,c; }arr[kmaxn]; inline int lowbit(int x) { return x&(-x); } void add(int pos,ll k) { for(reg int i=pos;i>0&&i<=n;i+=lowbit(i)) { tree[i]+=k; } } ll query(int pos) { ll ans=0; for(reg int i=pos;i>0;i-=lowbit(i)) { ans+=tree[i]; } return ans; } const bool cmp(const unit& u1,const unit& u2) { return u1.x<u2.x; } const bool cmp2(const unit& u1,const unit& u2) { return u1.k==u2.k?u1.inf<u2.inf:u1.k>u2.k; } void cdq(int l,int r) { if(l>=r) return; int mid=(l+r)>>1; cdq(l,mid); cdq(mid+1,r); sort(arr+l,arr+mid+1,cmp); sort(arr+mid+1,arr+r+1,cmp); reg int i=mid+1,j=l; for(;i<=r;++i) { if(arr[i].k==ADD) continue; while(j<=mid&&arr[j].x<arr[i].x) { if(arr[j].k==ADD){ add(arr[j].y,arr[j].inf),s.push(j); // cout<<"add "<<arr[j].y<<" "<<arr[j].inf<<endl; } ++j; } // cout<<arr[i].x<<" x y "<<arr[i].y<<" "<<ans[arr[i].inf] <<" "; ans[arr[i].inf]+=query(arr[i].y-1); // cout<<ans[arr[i].inf]<<" "<<j<<endl; } while(!s.empty()){ add(arr[s.top()].y,-arr[s.top()].inf); s.pop(); } } int reqt; int main() { ios::sync_with_stdio(false); cin>>opt>>n; while(flag) { cin>>opt; switch(opt) { case 1: cin>>arr[t].x>>arr[t].y>>arr[t].inf; arr[t].k=ADD; ++t; break; case 2: cin>>a>>b>>c>>d; arr[t].inf=reqt++; arr[t].x=a; arr[t].y=b; ++t; arr[t].inf=reqt++; arr[t].x=a; arr[t].y=d+1; ++t; arr[t].inf=reqt++; arr[t].x=c+1; arr[t].y=b; ++t; arr[t].x=c+1; arr[t].y=d+1; arr[t].inf=reqt; arr[t].a=reqt-3; arr[t].b=reqt-2; arr[t].c=reqt-1; ++reqt; arr[t].k=REQ; ++t; break; case 3: flag=false; break; } } t-=1; cdq(0,t); sort(arr,arr+t+1,cmp2); for(reg int i=0;i<=t;++i) { //if(arr[i].k!=ADD)cout<<arr[i].x<<" "<<arr[i].y<<" "<<ans[arr[i].inf]<<endl; if(arr[i].k==REQ) { cout<<ans[arr[i].inf]-ans[arr[i].b]+ans[arr[i].a]-ans[arr[i].c]<<endl; // cout<<ans[arr[i].inf]<<endl<<ans[arr[i].b]<<endl<<ans[arr[i].c]<<endl<<ans[arr[i].a]<<endl; } } return 0; } /* 0 4 1 2 3 3 1 2 2 2 2 1 1 1 4 3 */ ```
by _虹_ @ 2019-03-08 16:02:54


你的第一个不满足小于的性质,sort会出奇怪的事
by 142857cs @ 2019-03-08 16:13:08


@[142857cs](/space/show?uid=35760) x相同时候才会判断add啊,不管x相同的部分,sort之后x应该都单调不降吧
by _虹_ @ 2019-03-08 17:44:31


@[_虹_](/space/show?uid=56184) 好像cmp函数在两个数相同时必须返回false否则会出奇怪的事
by 142857cs @ 2019-03-08 18:41:40


|