zoukankan      html  css  js  c++  java
  • [Violet]天使玩偶/SJY摆棋子

    传送门

    题目大意就是先给定n个点,然后m个操作,每次添加一个点或者查询离一个点最近的一个点是哪个点。

    因为要求的是曼哈顿距离,所以我们先把式子转化一下,就是((x_i + y_i) - (x_j + y_j)),也就是对于查询的点,求出时间早于它,且(x,y)都小于它的点中(x_i+y_i)最大的一个。这个可以用树状数组维护最大值。

    这个就是很简单的三维偏序,(CDQ)分治写一下就好了。不过这样只能找一个方向,一共有4个方向,每次用最大坐标分别减去横,纵坐标就可以实现旋转的效果了。

    不过有点虚,这个理论的复杂度是(O(4 imes(n+m)log(n+m)logmax_y)),好像怎么算都会超时……最后不得已之后不用(sort),改成用归并排序之后还得开(O2)才能过。

    看一下代码。

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #define rep(i,a,n) for(register int i = a;i <= n;i++)
    #define per(i,n,a) for(register int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define pr pair<int,int>
    #define mp make_pair
    #define fi first
    #define sc second
    #define lowbit(x) x & (-x)
    using namespace std;
    typedef long long ll;
    const int M = 300005;
    const int N = 1000005;
     
    inline int read()
    {
       int ans = 0,op = 1;
       char ch = getchar();
       while(ch < '0' || ch > '9')
       {
          if(ch == '-') op = -1;
          ch = getchar();
       }
       while(ch >='0' && ch <= '9')
       {
          ans *= 10;
          ans += ch - '0';
          ch = getchar();
       }
       return ans * op;
    }
    
    inline void write(int x)
    {
       if(x < 0) x = -x, putchar('-');
       if(x >= 10) write(x / 10);
       putchar(x % 10 + '0');
    }
    
    struct treearray
    {
       int c[N+10];
       void add(int x,int v) {while(x <= N+2) c[x] = max(c[x],v),x += lowbit(x);}
       int ask(int x) {int cur = 0;while(x) cur = max(cur,c[x]),x -= lowbit(x);return cur;}
       void clear(int x) {while(x <= N+2) c[x] = 0,x += lowbit(x);} 
    }T;
    
    struct node
    {
       int x,y,tim;
       bool operator < (const node &g) const
       {
          return x < g.x;
       }
    }a[M<<1],b[M<<1],t[M<<1];
    
    int n,m,cnt,op,Ti,ans[M];
    
    void CDQ(int l,int r)
    {
       if(l == r) return;
       int mid = (l+r) >> 1,p1 = l,p2 = mid+1;
       CDQ(l,mid),CDQ(mid+1,r);
       //sort(a+l,a+mid+1),sort(a+mid+1,a+r+1);
       rep(i,l,r)
       {
          if(p2 > r || (p1 <= mid && a[p1].x <= a[p2].x))
          {
         t[i] = a[p1++];
         if(!t[i].tim) T.add(t[i].y,t[i].x + t[i].y);
          }
          else
          {
         t[i] = a[p2++];
         if(!t[i].tim) continue;
         int k = T.ask(t[i].y);
         if(k) ans[t[i].tim] = min(ans[t[i].tim],t[i].x + t[i].y - k);
          }
       }
       rep(i,l,mid) if(!a[i].tim) T.clear(a[i].y);
       rep(i,l,r) a[i] = t[i];
    }
    
    int main()
    {
       memset(ans,0x3f,sizeof(ans));
       n = read(),m = read();
       rep(i,1,n) b[++cnt].x = read()+1,b[cnt].y = read()+1;
       rep(i,1,m)
       {
          op = read();
          if(op == 1) b[++cnt].x = read()+1,b[cnt].y = read()+1;
          else b[++cnt].x = read()+1,b[cnt].y = read()+1,b[cnt].tim = ++Ti;
       }
       rep(i,1,cnt) a[i] = b[i];
       CDQ(1,cnt);
       rep(i,1,cnt) a[i] = b[i],a[i].x = N - a[i].x;
       CDQ(1,cnt);
       rep(i,1,cnt) a[i] = b[i],a[i].y = N - a[i].y;
       CDQ(1,cnt);
       rep(i,1,cnt) a[i] = b[i],a[i].x = N - a[i].x,a[i].y = N - a[i].y;
       CDQ(1,cnt);
       rep(i,1,Ti) write(ans[i]),enter;
       return 0;
    }
    
    
  • 相关阅读:
    favicon.ico在线制作,在线Favicon.ico制作转换工具
    素材之家,中国免费素材下载网站!下免费素材就到素材之家!
    visual assit 2010 2008均可用
    SQL server2008卸载出现重启怎么解决
    ping测试网络
    inndy_rop
    BJDCTF 2nd web
    [BJDCTF 2nd]one_gadget
    bjdctf_2020_babystack2
    堆溢出之unlink
  • 原文地址:https://www.cnblogs.com/captain1/p/10090225.html
Copyright © 2011-2022 走看看