bzoj4170: 极光

这个东西花里胡哨的其实就是每次加一个点,问就是和当前点曼哈顿距离小于k的点数

发现覆盖范围是一个菱形,我们可以旋转坐标系,曼哈顿转切比雪夫

是矩形就变成裸三维偏序了

数据范围真TM毒瘤

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>

#define x first
#define y second
using namespace std;
typedef pair<int,int> pa;
const int maxn=61000;
const int maxQ=61000,maxC=61000;
const int maxm=maxC+maxQ*4;

//-----------------------------deq----------------------------------------------

int s[maxC+maxn];
int lowbit(int x){return x&-x;}
void change(int x,int k){ while(x<maxC+maxn){s[x]+=k;x+=lowbit(x);} }
int getsum(int x){ int ret=0; while(x>0){ret+=s[x];x-=lowbit(x);} return ret; }
//~~~~~~~~~~~~~~~~~3~~~~~~~~~~~~~~~~~~~~~~~~

struct query
{
    pa p;int id;
    query(){}
    query(pa P,int ID){p=P,id=ID;}
}q[maxm+maxn];int qlen,ak,as[maxQ];

query t[maxm+maxn];
void cdq(int l,int r)
{
    if(l==r)return ;
    int mid=(l+r)/2;
    cdq(l,mid),cdq(mid+1,r);
    
    int i=l,j=mid+1,p=l;
    while(i<=mid&&j<=r)
    {
        if(q[i].p.x<=q[j].p.x)
        {
            if(q[i].id==0)change(q[i].p.y,1);
            t[p++]=q[i++];
        }
        else
        {
            if(q[j].id!=0)as[abs(q[j].id)]+=(q[j].id>0?1:-1)*getsum(q[j].p.y);
            t[p++]=q[j++];
        }
    }
    while(i<=mid)
    {
        if(q[i].id==0)change(q[i].p.y,1);
        t[p++]=q[i++];
    }
    while(j<=r)
    {
        if(q[j].id!=0)as[abs(q[j].id)]+=(q[j].id>0?1:-1)*getsum(q[j].p.y);
        t[p++]=q[j++];
    }
    
    for(int i=l;i<=mid;i++)
        if(q[i].id==0)change(q[i].p.y,-1);
    for(int i=l;i<=r;i++)q[i]=t[i];
}
//~~~~~~~~~~~~~~~~~2~~~~~~~~~~~~~~~~~~~~~~~~

//-----------------------------solve--------------------------------------------

int a[maxn];char ss[10];
int xlen,ylen,lsx[maxm+maxn],lsy[maxm+maxn];
pa npt(int x,int y){return make_pair(x+y,x-y);}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int n,Q,u,k; pa pp;
    scanf("%d%d",&n,&Q);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),q[++qlen]=query(npt(i,a[i]),0);
        
    for(int i=1;i<=Q;i++)
    {
        scanf("%s",ss+1);
        if(ss[1]=='M')
        {
            scanf("%d%d",&u,&k);a[u]=k;
            q[++qlen]=query(npt(u,a[u]),0);
        }
        else
        {
            scanf("%d%d",&u,&k);ak++;
            pp=npt(u+k,a[u]);q[++qlen]=query(pp,ak);
            pp=npt(u-k,a[u]);pp.x--,pp.y--,q[++qlen]=query(pp,ak);
            pp=npt(u,a[u]+k);pp.y--;q[++qlen]=query(pp,-ak);
            pp=npt(u,a[u]-k);pp.x--;q[++qlen]=query(pp,-ak);
        }
    }
    
    for(int i=1;i<=qlen;i++)
        lsx[++xlen]=q[i].p.x,lsy[++ylen]=q[i].p.y;
    sort(lsx+1,lsx+xlen+1);
    sort(lsy+1,lsy+ylen+1);
    xlen=unique(lsx+1,lsx+xlen+1)-lsx-1;
    ylen=unique(lsy+1,lsy+ylen+1)-lsy-1;
    for(int i=1;i<=qlen;i++)
        q[i].p.x=lower_bound(lsx+1,lsx+xlen+1,q[i].p.x)-lsx,
        q[i].p.y=lower_bound(lsy+1,lsy+ylen+1,q[i].p.y)-lsy;
    
    cdq(1,qlen);
    for(int i=1;i<=ak;i++)printf("%d\n",as[i]);
    
    return 0;
}

 

posted @ 2019-01-23 10:13  AKCqhzdy  阅读(122)  评论(0编辑  收藏  举报