• 省队集训Day3 light


    【问题描述】
    “若是万一琪露诺(俗称 rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她。
    对方表现出兴趣的话,那就慢慢地反问。在她考虑答案的时候,趁机逃吧。就算是很简单的
    问题,她一定也答不上来。” ——《上古之魔书》

    天空中出现了许多的北极光,这些北极光组成了一个长度为 n 的正整数数列 a[i],远古之
    魔书上记载到:2 个位置的 graze 值为两者位置差与数值差的和:
    graze(x,y)=|x-y|+|a[x]-a[y]|。
    要想破解天罚,就必须支持 2 种操作(k 都是正整数):
    Modify x k:将第 x 个数的值修改为 k。
    Query x k:询问有几个 i 满足 graze(x,i)<=k。
    由于从前的天罚被圣王 lmc 破解了,所以 rhl 改进了她的法术,询问不仅要考虑当前数
    列,还要考虑任意历史版本,即统计任意位置上出现过的任意数值与当前的 a[x]的 graze 值
    <=k 的对数。(某位置多次修改为同样的数值,按多次统计)
    【输入格式】
    第 1 行两个整数 n,q。分别表示数列长度和操作数。
    第 2 行 n 个正整数,代表初始数列。
    第 3~q+2 行每行一个操作。
    【输出格式】
    对于每次询问操作,输出一个非负整数表示答案。
    【样例输入】
    3 5
    2 4 3
    Query 2 2
    Modify 1 3
    Query 2 2
    Modify 1 2
    Query 1 1
    【样例输出】
    2
    3
    3

    将每个元素看做一个点(x,A[x]),那么也就是询问一个斜着的正方形内有多少个
    点;或者修改一个点的 y 值。
    把斜着的正方形转成正着的正方形,也就是(x,y)->(x-y,x+y),然后变为查询矩形
    内部元素个数。

    然后就是CDQ裸题了··

    code:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define maxn 60005
     6 #define maxm 260005
     7 #define maxq 60005
     8 #define lowbit(x) ((x)&(-(x)))
     9 using namespace std;
    10 char s[6];
    11 int n,q,x,k,cnt,lim,a[maxn],ans[(maxn+maxq)*4];
    12 bool bo[maxn+maxq];
    13 struct DATA{
    14     int num,id,op,x,y,t;
    15 }list[(maxn+maxq)*4],p,temp[(maxn+maxq)*4];
    16 void add(int op,int id,int x,int y,int k){
    17     int xx=x-y,yy=x+y;
    18     if (!op) lim=max(lim,xx),lim=max(lim,yy),list[++cnt]=(DATA){cnt,id,op,xx,yy,0};
    19     else{
    20         int x1=xx-k,y1=yy-k,x2=xx+k,y2=yy+k;
    21         if (y1>0) list[++cnt]=(DATA){cnt,id,op,x1-1,y1-1,1};
    22         list[++cnt]=(DATA){cnt,id,op,x1-1,y2,-1};
    23         if (y1>0) list[++cnt]=(DATA){cnt,id,op,x2,y1-1,-1};
    24         list[++cnt]=(DATA){cnt,id,op,x2,y2,1};
    25         lim=max(lim,x2),lim=max(lim,y2);
    26     }
    27 }
    28 struct bit{
    29     int val[maxm];
    30     void insert(int x,int v){for (;x<=lim;x+=lowbit(x)) val[x]+=v;}
    31     int query(int x){
    32         int ans=0;
    33         for (;x;x-=lowbit(x)) ans+=val[x];
    34         return ans;
    35     }
    36 }T;
    37 void solve(int l,int r){
    38     if (l==r) return;
    39     int m=(l+r)>>1;
    40     solve(l,m),solve(m+1,r);
    41     for (int i=l,a=l,b=m+1;i<=r;i++){
    42         p=(a<=m&&(b>r||list[a].x<=list[b].x))?list[a++]:list[b++];
    43         if (p.num<=m&&!p.op) T.insert(p.y,1);
    44         else if (p.num>m&&p.op) ans[p.id]+=T.query(p.y)*p.t;
    45         temp[i]=p;
    46     }
    47     for (int i=l;i<=r;i++) list[i]=temp[i];
    48     for (int i=l;i<=r;i++) if (list[i].num<=m&&!list[i].op) T.insert(list[i].y,-1);
    49 }
    50 int main(){
    51     scanf("%d%d",&n,&q);
    52     for (int i=1;i<=n;i++){
    53         scanf("%d",&a[i]);
    54         add(0,i,i,a[i],0);
    55     }
    56     for (int i=n+1;i<=n+q;i++){
    57         scanf("%s%d%d",s,&x,&k);
    58         if (s[0]=='M') a[x]=k,add(0,i,x,a[x],0);
    59         else{
    60             bo[i]=1;
    61             add(1,i,x,a[x],k);
    62         }
    63     }
    64     n+=q,lim++,solve(1,cnt);
    65     for (int i=1;i<=n;i++) if (bo[i]) printf("%d
    ",ans[i]);
    66     return 0;
    67 }
  • 相关阅读:
    继续致歉
    向大家致歉!!
    访问速度调查
    致歉
    [功能改进]通过Blog客户端直接发随笔至网站分类
    带宽升级公告
    创业团队的类型
    [讨论]基于.NET的开源论坛软件的选择
    调整一下工作的节奏
    公告
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4622579.html
Copyright © 2020-2023  润新知