bzoj 2989: 数列&4170: 极光
2017-12-05 21:15
351 查看
题意:
平面支持加点,多次询问与一个点曼哈顿距离<=k的点的个数。题解:
容易想到四维偏序,但显然过不了画一画图,可以发现满足条件的点在一个菱形里面,旋转45度就是一个正方形了。
于是将(x,y)变成(x−y,x+y),相当于斜着做一个坐标系,然后三维偏序就行了。
code:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; struct node{ int op,x,y,c; }q[1500000],tmp[1500000];int cnt=0,qcnt=0,Q[1500000],tr[2000010]; int n,m,a[400010],ans[100010]; void add(int op,int X,int Y,int c) {q[++cnt].op=op;q[cnt].x=X-Y;q[cnt].y=X+Y;q[cnt].c=c;} int lowbit(int x) {return x&(-x);} vo 12f4e id change(int k,int c) {k=max(k,0);k++;for(int i=k;i<=2000001;i+=lowbit(i)) tr[i]+=c;} void rechange(int k) {k=max(k,0);k++;for(int i=k;i<=2000001;i+=lowbit(i)) tr[i]=0;} int get(int k) {k++;int ANS=0;for(int i=k;i>=1;i-=lowbit(i)) ANS+=tr[i];return ANS;} int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*f; } 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,len=0,st=0; while(i<=mid&&j<=r) { if(q[i].x<=q[j].x) { if(q[i].op==1) change(q[i].y,1),Q[++st]=q[i].y; tmp[++len]=q[i++]; } else { if(q[j].y<0) {tmp[++len]=q[j++];continue;} int num=get(q[j].y); if(q[j].op==2) ans[q[j].c]+=num; else ans[q[j].c]-=num; tmp[++len]=q[j++]; } } while(i<=mid) tmp[++len]=q[i++]; while(j<=r) { if(q[j].y<0) {tmp[++len]=q[j++];continue;} int num=get(q[j].y); if(q[j].op==2) ans[q[j].c]+=num; else ans[q[j].c]-=num; tmp[++len]=q[j++]; } for(i=1;i<=len;i++) q[l+i-1]=tmp[i]; for(i=1;i<=st;i++) rechange(Q[i]); } int main() { n=read();m=read(); for(int i=1;i<=n;i++) { int x;x=read(); add(1,i,x,0);a[i]=x; } char s[10]; for(int i=1;i<=m;i++) { scanf("%s",s+1); if(s[1]=='M') { int x,y;x=read();y=read(); add(1,x,y,0);a[x]=y; } else { int x,y,k;x=read();k=read();y=a[x]; add(2,x+k,y,++qcnt);add(2,x-k-1,y,qcnt); q[++cnt].op=3;q[cnt].x=x-y-k-1;q[cnt].y=x+y+k;q[cnt].c=qcnt; q[++cnt].op=3;q[cnt].x=x-y+k;q[cnt].y=x+y-k-1;q[cnt].c=qcnt; } } cdq(1,cnt); for(int i=1;i<=qcnt;i++) printf("%d\n",ans[i]); }
相关文章推荐
- BZOJ_2989_数列&&BZOJ_4170_极光_KDTree
- [BZOJ]4170: 极光 2989: 数列 CDQ分治+树状数组
- BZOJ2989 数列/BZOJ4170 极光
- bzoj2989: 数列&&4170: 极光
- bzoj 2989&&4170: 数列
- BZOJ 2989 数列
- [BZOJ1485] [HNOI2009]有趣的数列 && 找规律 + 数学
- 无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )
- 【bzoj2989】【数列】【cdq分治+树状数组】
- bzoj2656 数列 高精度&递推
- 【BZOJ2989】数列 kd-tree
- 【bzoj2989】数列 KD-tree+旋转坐标系
- bzoj2989&4170: 数列
- BZOJ 2989 数列 变换坐标系 主席树
- BZOJ4170 极光(CDQ分治 或 树套树)
- BZOJ4170 极光(CDQ分治 或 树套树)
- 【线段树】BZOJ2989 数列
- BZOJ2989 数列(二进制分组)
- 【BZOJ 4170】 4170: 极光 (CDQ分治)
- [您有新的未分配科技点] 无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )