zoukankan      html  css  js  c++  java
  • [NOI2012]魔幻棋盘

    这一道题的话就我而言可能更像数学里的分类讨论?

    就是讨论一下修改矩形的四个角在守护者的哪边就好了,只是我的代码可能有点麻烦,如果有神犇看到的话能给点建议吗,拜谢!

    然后很多东西我会放在代码里面,大佬们就看代码吧

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    #include <cstring>
    #include <queue>
    #include <complex>
    #include <stack>
    #define LL long long int
    #define dob double
    #define FILE "chessa"
    //#define FILE "魔幻棋盘"
    using namespace std;
    const int N = 500010;
    int n,m,X,Y,q,rt,tot;
    struct Array{//来自BOBOYANG的黑科技
      LL t[N];
      LL *operator [](int x){return &t[(x-1)*m];}
    }A;
    struct Tree{int l,r,ls,rs,tree;LL val;}T[N<<4];
    inline LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
    inline LL gi(){
      LL x=0,res=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
      while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
      return x*res;
    }
    namespace Seg{
      inline void build(int &x,int l,int r,int id){
        x=++tot,T[x].l=l,T[x].r=r;int mid=(l+r)>>1;
        if(l==r){T[x].val=A[id][l];return;}
        build(T[x].ls,l,mid,id);build(T[x].rs,mid+1,r,id);
        T[x].val=gcd(T[T[x].ls].val,T[T[x].rs].val);
      }
      inline LL query(int x,int xl,int xr){
        int l=T[x].l,r=T[x].r,mid=(l+r)>>1;
        if(l==xl && r==xr)return T[x].val;
        if(xr<=mid)return query(T[x].ls,xl,xr);
        if(xl>mid)return query(T[x].rs,xl,xr);
        return gcd(query(T[x].ls,xl,mid),query(T[x].rs,mid+1,xr));
      }
      inline void update(int x,int xp,LL val){
        int l=T[x].l,r=T[x].r,mid=(l+r)>>1;
        if(l==r){T[x].val+=val;return;}
        if(xp<=mid)update(T[x].ls,xp,val);
        else update(T[x].rs,xp,val);
        T[x].val=gcd(T[T[x].ls].val,T[T[x].rs].val);
      }
    }
    namespace TwoD_Segment_Tree{
      inline void merge(int &x,int r1,int r2,int s,int t){
        if(!x)x=++tot,T[x].l=s,T[x].r=t;int mid=(s+t)>>1;
        if(s==t){T[x].val=gcd(T[r1].val,T[r2].val);return;}
        merge(T[x].ls,T[r1].ls,T[r2].ls,s,mid);
        merge(T[x].rs,T[r1].rs,T[r2].rs,mid+1,t);
        T[x].val=gcd(T[T[x].ls].val,T[T[x].rs].val);
      }
      inline void build(int &x,int s,int t){
        x=++tot;T[x].l=s;T[x].r=t;int mid=(s+t)>>1;
        if(s==t){Seg::build(T[x].tree,1,m,s);return;}
        build(T[x].ls,s,mid);build(T[x].rs,mid+1,t);
        merge(T[x].tree,T[T[x].ls].tree,T[T[x].rs].tree,1,m);
      }
      inline LL query(int x,int x1,int x2,int y1,int y2){
        int l=T[x].l,r=T[x].r,mid=(l+r)>>1;
        if(l==x1 && r==x2)return Seg::query(T[x].tree,y1,y2);
        if(x2<=mid)return query(T[x].ls,x1,x2,y1,y2);
        if(x1>mid)return query(T[x].rs,x1,x2,y1,y2);
        return gcd(query(T[x].ls,x1,mid,y1,y2),query(T[x].rs,mid+1,x2,y1,y2));
      }
      inline void update(int x,int xp,int y,LL val){
        int l=T[x].l,r=T[x].r,mid=(l+r)>>1;
        if(l==r){Seg::update(T[x].tree,y,val);return;}
        if(xp<=mid)update(T[x].ls,xp,y,val);
        else update(T[x].rs,xp,y,val);
        LL lval=Seg::query(T[T[x].ls].tree,y,y);
        LL rval=Seg::query(T[T[x].rs].tree,y,y);
        LL mval=Seg::query(T[x].tree,y,y);
        Seg::update(T[x].tree,y,gcd(lval,rval)-mval);
      }
    }
    using namespace TwoD_Segment_Tree;
    int main()
    {
      n=gi();m=gi();X=gi();Y=gi();q=gi();
      for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
          A[i][j]=gi();
      for(int i=1;i<=n;++i){
        for(int j=1;j<Y;++j)A[i][j]-=A[i][j+1];
        for(int j=m;j>Y;--j)A[i][j]-=A[i][j-1];
      }
      for(int j=1;j<=m;++j){
        for(int i=1;i<X;++i)A[i][j]-=A[i+1][j];
        for(int i=n;i>X;--i)A[i][j]-=A[i-1][j];
      }
      build(rt,1,n);
      for(int t=1,type,x1,y1,x2,y2;t<=q;++t){
        scanf("%d%d%d%d%d",&type,&x1,&y1,&x2,&y2);
        if(type==0){
          x1=X-x1;y1=Y-y1;x2=X+x2;y2=Y+y2;
          printf("%lld
    ",abs(query(rt,x1,x2,y1,y2)));
        }
        if(type==1){
          LL val=gi();
          //讨论修改矩形的四个角在守护者的哪边。
          //左上角(x1,y1)
          /*在守护者左上*/if(x1<=X && y1<=Y && x1>1 && y1>1)update(rt,x1-1,y1-1,val);
          /*在守护者右上*/if(x1<=X && y1>Y && x1>1)update(rt,x1-1,y1,-val);
          /*在守护者左下*/if(x1>X && y1<=Y && y1>1)update(rt,x1,y1-1,-val);
          /*在守护者右下*/if(x1>X && y1>Y)update(rt,x1,y1,val);
          //右上角(x1,y2)
          /*在守护者左上*/if(x1<=X && y2<Y && x1>1)update(rt,x1-1,y2,-val);
          /*在守护者右上*/if(x1<=X && y2>=Y && x1>1 && y2<m)update(rt,x1-1,y2+1,val);
          /*在守护者左下*/if(x1>X && y2<Y)update(rt,x1,y2,val);
          /*在守护者右下*/if(x1>X && y2>=Y && y2<m)update(rt,x1,y2+1,-val);
          //左下角(x2,y1)
          /*在守护者左上*/if(x2<X && y1<=Y && y1>1)update(rt,x2,y1-1,-val);
          /*在守护者右上*/if(x2<X && y1>Y)update(rt,x2,y1,val);
          /*在守护者左下*/if(x2>=X && y1<=Y && x2<n && y1>1)update(rt,x2+1,y1-1,val);
          /*在守护者右下*/if(x2>=X && y1>Y && x2<n)update(rt,x2+1,y1,-val);
          //右下角(x2,y2)
          /*在守护者左上*/if(x2<X && y2<Y)update(rt,x2,y2,val);
          /*在守护者右上*/if(x2<X && y2>=Y && y2<m)update(rt,x2,y2+1,-val);
          /*在守护者左下*/if(x2>=X && y2<Y && x2<n)update(rt,x2+1,y2,-val);
          /*在守护者右下*/if(x2>=X && y2>=Y && x2<n && y2<m)update(rt,x2+1,y2+1,val);
          //讨论修改矩形的四条边跨守护者十字情况。
          //矩形竖边对守护者横线的影响
          if(x1<=X && x2>=X){
            //左边(x1,y1) -> (x2,y1)
            /*跨左横线*/if(y1<=Y && y1>1)update(rt,X,y1-1,-val);
            /*跨右横线*/if(y1>Y)update(rt,X,y1,val);      
            //右边(x1,y2) -> (x2,y2)
            /*跨左横线*/if(y2<Y)update(rt,X,y2,val);
            /*跨右横线*/if(y2>=Y && y2<m)update(rt,X,y2+1,-val);
          }
          //矩形横边对守护者竖线的影响
          if(y1<=Y && y2>=Y){
            //上边(x1,y1) -> (x1,y2)
            /*跨上竖线*/if(x1<=X && x1>1)update(rt,x1-1,Y,-val);
            /*跨下竖线*/if(x1>X)update(rt,x1,Y,val);
            //下边(x2,y1) -> (x2,y2)
            /*跨上竖线*/if(x2<X)update(rt,x2,Y,val);
            /*跨下竖线*/if(x2>=X && x2<n)update(rt,x2+1,Y,-val);
          }      
          if(x1<=X && x2>=X && y1<=Y && y2>=Y)update(rt,X,Y,val);
        }
      }
      return 0;
    }
    
  • 相关阅读:
    python中实现mysql连接池
    flask简单的路由分发
    用进程池创建子进程
    用类创建子进程
    用函数创建子进程
    fiddler抓包工具使用
    requests库的小技巧
    requests库的get请求,带有cookies
    requests库的post请求
    Android下Json数据解析
  • 原文地址:https://www.cnblogs.com/zi-nai-boboyang/p/11437182.html
Copyright © 2011-2022 走看看