zoukankan      html  css  js  c++  java
  • 【CF575I】Robots protection(二维树状数组)

    点此看题面

    • 有一张(n imes n)的二维平面。
    • (q)次操作,分为两种:摆放一个两直角边平行于坐标轴的等腰直角三角形;询问一个点被多少三角形覆盖。
    • (nle5 imes10^3,qle10^5)

    二维树状数组

    以斜边在左上方的直角三角形为例(可以通过每次将整个二维平面旋转(90^circ)把四种直角三角形都化为这种情况)。

    假设它的顶点坐标是((x,y)),边长是(l),那么被它覆盖的点((X,Y))就需要满足:(X+Yle x+y+l)(Xge x)(Yge y)

    此时我们可以直接用树套树套树解决此题。

    考虑我们修改一下条件,添上(X+Yge x+y)这个必要条件,则(Xge x)(Yge y)最多只有一个不满足。

    因此我们容斥,给所有满足(x+yle X+Yle x+y+l)的点加(1),再给满足这个条件的前提下所有(X<x)(Y<y)的点分别减(1)

    这样一来只需要一个树状数组和两个二维树状数组就解决了此题。

    代码:(O(qlog^2n))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 5000
    #define M 100000
    using namespace std;
    int n,Qt,ans[M+5];struct OP {int op,x,y,d,l;}q[M+5];
    namespace FastIO
    {
    	#define FS 100000
    	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
    	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
    	int OT;char oc,FI[FS],FO[FS],OS[FS],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
    	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
    	Tp I void read(Ty& x) {x=0;W(!isdigit(oc=tc()));W(x=(x<<3)+(x<<1)+(oc&15),isdigit(oc=tc()));}
    	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    	Tp I void writeln(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc('
    ');}
    }using namespace FastIO;
    struct TreeArray//树状数组
    {
    	int a[2*N+5];I void Cl() {for(RI i=0;i<=2*n;++i) a[i]=0;}
    	I void U_(RI x,CI v) {W(x<=2*n) a[x]+=v,x+=x&-x;}I void U(CI x,CI y) {U_(x,1),U_(y+1,-1);}
    	I int Q(RI x,RI t=0) {W(x) t+=a[x],x-=x&-x;return t;}
    }T;
    struct TreeArray2//二维树状数组
    {
    	int a[2*N+5][N+5];I void Cl() {for(RI i=0;i<=2*n;++i) for(RI j=0;j<=n;++j) a[i][j]=0;}
    	I void U1(int* a,RI x,RI v) {W(x) a[x]+=v,x-=x&-x;}
    	I void U2(RI x,CI y,CI v) {W(x<=2*n) U1(a[x],y,v),x+=x&-x;}
    	I void U(CI x1,CI x2,CI y) {U2(x1,y,1),U2(x2+1,y,-1);}
    	I int Q(int* a,RI x,RI t=0) {W(x<=n) t+=a[x],x+=x&-x;return t;}
    	I int Q(RI x,CI y,RI t=0) {W(x) t+=Q(a[x],y),x-=x&-x;return t;}
    }X,Y;
    int main()
    {
    	RI i;for(read(n,Qt),i=1;i<=Qt;++i) read(q[i].op),
    		q[i].op==1?(read(q[i].d,q[i].x,q[i].y,q[i].l),q[i].d>2&&(q[i].d=7-q[i].d)):(read(q[i].x,q[i].y),0);//交换3,4类型,方便旋转
    	for(RI D=1,l,r;D<=4;++D) for(T.Cl(),X.Cl(),Y.Cl(),i=1;i<=Qt;swap(q[i].x,q[i].y),q[i].x=n-q[i].x+1,++i)//枚举类型,每次将所有点旋转90°
    		q[i].op==1&&q[i].d==D&&(T.U(l=q[i].x+q[i].y,r=q[i].x+q[i].y+q[i].l),X.U(l,r,q[i].x-1),Y.U(l,r,q[i].y-1),0),//放置这种类型的三角形
    		q[i].op==2&&(ans[i]+=T.Q(q[i].x+q[i].y)-X.Q(q[i].x+q[i].y,q[i].x)-Y.Q(q[i].x+q[i].y,q[i].y));//询问,用总情况减去两种不合法情况
    	for(i=1;i<=Qt;++i) q[i].op==2&&(writeln(ans[i]),0);return clear(),0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    html input type=file 选择图片,图片预览 纯html js实现图片预览
    asp.net mvc Controller控制器返回类型
    webrequest HttpWebRequest webclient/HttpClient
    js中__proto__和prototype constructor 的区别和关系
    JQuery的ajaxFileUpload的使用
    cuda中当数组数大于线程数的处理方法
    cuda中threadIdx、blockIdx、blockDim和gridDim的使用
    cuda和gcc版本不兼容
    【转】CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)
    matlab练习程序(地图上画经纬度)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF575I.html
Copyright © 2011-2022 走看看