牛客网暑期ACM多校训练营(第二场)J

题解:CDQ维护即可 复杂度nlogn

#include <bits/stdc++.h>
const int MAXN=2e6+10;
#define ll long long
using namespace std;
typedef struct node{
    int x,y,vul;int flag;
    friend bool operator<(node aa,node bb){
    if(aa.x==bb.x&&aa.y==bb.y)return aa.flag>bb.flag;
    else if(aa.x==bb.x) return aa.y>bb.y;
    return aa.x>bb.x;
    }
}node;
node d[MAXN*5],d1[MAXN*5];
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int n,m,q,sz;
int ans[MAXN];int p,num[MAXN];
int cnt1=0;
void cdq(int l,int mid,int r){
    int i=l;int j=mid+1;cnt1=0;p=0;
    while(i<=mid&&j<=r){
    while(i<=mid&&d[i].y>=d[j].y){
        d1[++cnt1]=d[i];
        if(d[i].flag==2){p--;num[d[i].vul]--;}
        if(d[i].flag==1){p++;num[d[i].vul]++;}
        i++;
    }
    if(!d[j].flag)ans[(d[j].x-1)*m+d[j].y]+=p-num[d[j].vul];
    d1[++cnt1]=d[j];j++;
    }
    if(i<=mid){
    for(;i<=mid;i++)d1[++cnt1]=d[i];
    }
    if(j<=r){
    for(;j<=r;j++){
        if(!d[j].flag)ans[(d[j].x-1)*m+d[j].y]+=p-num[d[j].vul];
        d1[++cnt1]=d[j];
         }
    }
    for(int i=1;i<=cnt1;i++)d[l+i-1]=d1[i],num[d1[i].vul]=0;
}
void guibin(int l,int r){
    if(l>=r)return ;
    int mid=(l+r)>>1;
    guibin(l,mid);
    guibin(mid+1,r);
    cdq(l,mid,r);
}
int main(){
    n=read();m=read();q=read();
    int cnt=0;sz=(n)*(m);
    for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
        d[++cnt].x=i;d[cnt].y=j;d[cnt].vul=read();d[cnt].flag=0;
    }
    }
    int x1,y1,x2,y2,vul;
    for(int i=1;i<=q;i++){
    x1=read();y1=read();x2=read();y2=read();vul=read();
    d[++cnt].x=x2;d[cnt].y=y2;d[cnt].vul=vul;d[cnt].flag=1;
    d[++cnt].x=x1-1;d[cnt].y=y2;d[cnt].vul=vul;d[cnt].flag=2;
    d[++cnt].x=x2;d[cnt].y=y1-1;d[cnt].vul=vul;d[cnt].flag=2;
    d[++cnt].x=x1-1;d[cnt].y=y1-1;d[cnt].vul=vul;d[cnt].flag=1;
    }
    sort(d+1,d+cnt+1);
//    cout<<"====="<<endl;
//    for(int i=1;i<=cnt;i++)cout<<d[i].x<<" "<<d[i].y<<" "<<d[i].flag<<endl;
//    cout<<"====="<<endl;
    guibin(1,cnt);
//    for(int i=1;i<=sz;i++)cout<<ans[i]<<" ";
//    cout<<endl;
    int ans1=0;
    for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
        if(ans[(i-1)*m+j]>=1)ans1++;
        }
    }
    printf("%d\n",ans1);
    return 0;
}

 

posted @ 2018-07-22 02:50  wang9897  阅读(152)  评论(0编辑  收藏  举报