zoukankan      html  css  js  c++  java
  • Why Did the Cow Cross the Road III HYSBZ

    •  HYSBZ - 4991 
    • 题意: 第一列 1-n的排列 ,第二列 1-n的排列。  相同数字连边  ,问  有多少组 数字 是有交点的并且 绝对值之差>K
      思路:处理一下 1-n 在第一列的位置,1-n在第二列的位置。按照第一列的位置从小到大排序,然后 进行cdq分治,
      因为现在第一列已经是递增序列了,如果在第二列中出现了递减那么这两个数就有交点,分治解决,递归左区间 
      的必然第一列必然小于递归右区间。所以只处理左区间对右区间的影响,两段小区间分别按照 b 从大到小排序,
      然后 统计 左区间的b  比右区间大的树状数组更新那个数字。然后更新完成之后查询, 右区间当前的数
      (绝对值之差>K无非就是, < x-k  有多少 ,  > x+k有多少)分别 树状数组进行查询,进行完成之后 ,
      数组数组恢复最初状态,回溯 继续处理大区间即可

    • #include<bits/stdc++.h>
      using namespace std;
      #define ll long long
      #define maxn 100010
      struct node
      {
          int num,a,b;
      } data[maxn];
      bool cp(node x,node y)
      {
          return x.a<y.a;
      };
      bool cp2(node x,node y)
      {
          return x.b>y.b;
      };
      int tree[maxn],n,k,x;
      ll ans;
      int lowbit(int x)
      {
          return x&(-x);
      }
      void add(int x,int ad)
      {
          while(x<=n)
          {
              tree[x]+=ad;
              x+=lowbit(x);
          }
      }
      int query(int x)
      {
          int re=0;
          while(x>0)
          {
              re+=tree[x];
              x-=lowbit(x);
          }
          return re;
      }
      void cdq(int l,int r)
      {
          if(l==r)return ;
          int mid=(l+r)>>1;
          cdq(l,mid);
          cdq(mid+1,r);
          sort(data+l,data+1+mid,cp2);
          sort(data+mid+1,data+1+r,cp2);
          int i=l,j=mid+1;
          for(; j<=r; j++)
          {
              while(data[i].b>data[j].b&&i<=mid)
              {
                  add(data[i].num,1);
                  i++;
              }
              ans+=query(data[j].num-k-1);
              if(data[j].num+k<n)ans+=query(n)-query(data[j].num+k);
          }
          for(j=l; j<i; j++)
              add(data[j].num,-1);
      }
      int main()
      {
          scanf("%d%d",&n,&k);
          for(int i=1; i<=n; i++)
          {
              scanf("%d",&x);
              data[i].num=i;
              data[x].a=i;
          }
          for(int j=1; j<=n; j++)
          {
              scanf("%d",&x);
              data[x].b=j;
          }
          sort(data+1,data+1+n,cp);
          cdq(1,n);
          printf("%lld
      ",ans);
          return 0;
      }
      

        

  • 相关阅读:
    C++文件读写详解(ofstream,ifstream,fstream)
    C++ char*,const char*,string,int 的相互转换
    Properties --- C++读配置信息的类
    值得推荐的C/C++框架和库
    leetcode 264: Ugly Number II
    几种Tab的实现方法
    HBase数据存储格式
    粗略。。Java项目设计模式之笔记----studying
    开放的平台、向上的文化——揭秘万达电商(4)
    RecyclerView
  • 原文地址:https://www.cnblogs.com/SDUTNING/p/10261631.html
Copyright © 2011-2022 走看看