BZOJ 2989: 数列/4170: 极光

11 篇文章 0 订阅
5 篇文章 0 订阅

双倍经验题~2333
这道题的modify其实就是加点。。
有两种思路
一种是把它当成曼哈顿距离 那就是一个菱形区域 再把它转一下就是一个矩形 接着加上时间限制就是三个限制 三位偏序 嗯。。(我比较蠢 不会这种)
另一种就是列不等式 分类讨论~
转自嘎神
合并一下
同理也搞一下(2)(3)就得出两个限制
加上时间 也是一样的三位偏序
代码有点丑。。。QAQ

#include<bits/stdc++.h>
using namespace std;
const int N=150002,M=200000;
inline int read()
{
    char ch=getchar(); int x=0,f=1;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
struct node{int x,y,i,k;}p[N],a[N],b[N];
bool Cmp(node x1,node x2){return x1.x<x2.x;}
int ans[N],t[M*2+2],n;
void add(int x,int u){for(;x<=M*2;x+=x&-x)t[x]+=u;}
int query(int x){int s=0; for(;x;x-=x&-x)s+=t[x]; return s;}
void solve(int l,int r)
{
    if(l==r)return;
    int i,j,mid=(l+r)>>1,al=0,bl=0;
    for(i=l;i<=mid;i++) if(!p[i].i) a[++al]=p[i];
    for(i=mid+1;i<=r;i++) if(p[i].i)
    {
        b[++bl]=p[i],b[bl].i=i;
        b[bl].x=p[i].x+p[i].k;
        b[++bl]=p[i],b[bl].i=-i;
        b[bl].x=p[i].x-p[i].k-1;
    }
    sort(a+1,a+1+al,Cmp);
    sort(b+1,b+1+bl,Cmp);
    for(j=i=1;i<=bl;i++)
    {
        while(a[j].x<=b[i].x && j<=al)
            add(a[j].y+M,1),j++;
        int u=query(min(b[i].y+b[i].k+M,M<<1))-query(max(0,b[i].y-b[i].k+M-1));
        if(b[i].i>0) ans[b[i].i]+=u;
        else ans[-b[i].i]-=u;
    }
    for(j=j-1;j;j--) add(a[j].y+M,-1);
    solve(l,mid),solve(mid+1,r);
}
char c[15]; int h[N];
int main()
{
    int i,x,y,n=read(),m=read(),q=0;
    for(i=1;i<=n;i++)
    {
        h[i]=x=read();
        p[++q]=(node){i-x,i+x,0,0};
    }
    for(i=1;i<=m;i++)
    {
        scanf("%s",c); x=read(),y=read();
        if(c[0]=='Q')p[++q]=(node){x-h[x],x+h[x],1,y};
        else h[x]=y,p[++q]=(node){x-h[x],x+h[x],0,0};
    }
    solve(1,q);
    for(i=1;i<=q;i++)if(p[i].i)printf("%d\n",ans[i]);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值