省队集训Day3 light
2015-07-05 16:52
429 查看
【问题描述】
“若是万一琪露诺(俗称 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:
“若是万一琪露诺(俗称 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:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define maxn 60005 #define maxm 260005 #define maxq 60005 #define lowbit(x) ((x)&(-(x))) using namespace std; char s[6]; int n,q,x,k,cnt,lim,a[maxn],ans[(maxn+maxq)*4]; bool bo[maxn+maxq]; struct DATA{ int num,id,op,x,y,t; }list[(maxn+maxq)*4],p,temp[(maxn+maxq)*4]; void add(int op,int id,int x,int y,int k){ int xx=x-y,yy=x+y; if (!op) lim=max(lim,xx),lim=max(lim,yy),list[++cnt]=(DATA){cnt,id,op,xx,yy,0}; else{ int x1=xx-k,y1=yy-k,x2=xx+k,y2=yy+k; if (y1>0) list[++cnt]=(DATA){cnt,id,op,x1-1,y1-1,1}; list[++cnt]=(DATA){cnt,id,op,x1-1,y2,-1}; if (y1>0) list[++cnt]=(DATA){cnt,id,op,x2,y1-1,-1}; list[++cnt]=(DATA){cnt,id,op,x2,y2,1}; lim=max(lim,x2),lim=max(lim,y2); } } struct bit{ int val[maxm]; void insert(int x,int v){for (;x<=lim;x+=lowbit(x)) val[x]+=v;} int query(int x){ int ans=0; for (;x;x-=lowbit(x)) ans+=val[x]; return ans; } }T; void solve(int l,int r){ if (l==r) return; int m=(l+r)>>1; solve(l,m),solve(m+1,r); for (int i=l,a=l,b=m+1;i<=r;i++){ p=(a<=m&&(b>r||list[a].x<=list[b].x))?list[a++]:list[b++]; if (p.num<=m&&!p.op) T.insert(p.y,1); else if (p.num>m&&p.op) ans[p.id]+=T.query(p.y)*p.t; temp[i]=p; } for (int i=l;i<=r;i++) list[i]=temp[i]; for (int i=l;i<=r;i++) if (list[i].num<=m&&!list[i].op) T.insert(list[i].y,-1); } int main(){ scanf("%d%d",&n,&q); for (int i=1;i<=n;i++){ scanf("%d",&a[i]); add(0,i,i,a[i],0); } for (int i=n+1;i<=n+q;i++){ scanf("%s%d%d",s,&x,&k); if (s[0]=='M') a[x]=k,add(0,i,x,a[x],0); else{ bo[i]=1; add(1,i,x,a[x],k); } } n+=q,lim++,solve(1,cnt); for (int i=1;i<=n;i++) if (bo[i]) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- Servlet - Java Web Core Component
- How to Copy and Paste in the Ubuntu Gnome Terminal
- JDK、JRE和JVM三者之间的关系
- Java EE发展史
- Linux下获取块设备大小
- 【C++】通用单链表
- String Transmission
- 【软件测试】5、单元测试
- 基于ACIS/HOOPS的3D应用开发简介 【转】
- Oracle ->> Oracle下生成序列的方法
- 协议设计中ACK机制的影响
- 《java课程设计》之猜猜看游戏(四)
- leetcode_219题——Contains Duplicate II(哈希表)
- 【CF】174 Div.1 B Cow Program
- 【牛腩】真假分页
- javaSE学习笔记之面向对象程序设计(二)
- 省队集训Day3 tree
- Git 常用命令
- 【iOS】网络加载图片缓存与SDWebImage
- QT获取组合键