解题报告:Codeforces Round #433 (Div. 2) E. Boredom ( 离线处理+树状数组)

题目链接

题意:

n*n的矩阵,有n个不同行列的格子染色,染色的格子两两之间组成的矩阵定义为beautiful。

q组询问,每次给出一个矩阵,询问与它相交的beautiful的矩阵的数目

n,q<=2e5

思路:

每次查询分成九个矩阵,只需要知道各个矩阵中的染色的点数,即可得出答案

其中五个矩阵可以由染色的性质可以直接得出答案

离线处理另外四个即可

代码:

#include<bits/stdc++.h>

#define lowbit(x) (x&-x)
#define pii pair<int,int>
#define fi first
#define se second
#define LL long long
const int N = 2e5+10;
using namespace std;

int n,q;
int num[N][9];
struct node{
   int x,y,pos;
}Q[N<<2];
int bit[1<<20];
pii P[N];

inline LL C2(int x){return 1LL * x * (x-1) / 2 ;}
void add(int x){
   while(x<=n){
      ++bit[x];
      x+=lowbit(x);
   }
}

int query(int x){
   int res = 0;
   while(x){
      res += bit[x];
      x -= lowbit(x);
   }return res;
}

int main()
{
   scanf("%d%d",&n,&q);
   for(int i=1,x;i<=n;++i){
      scanf("%d",&x);
      P[i-1] = pii(i,x);
   }for(int i=0,l,d,r,u,j=0,k;i<q;i++){
      k = i*9;
      scanf("%d%d%d%d",&l,&d,&r,&u);--l;--d;
      Q[j++] = node{l,d,k};
      Q[j++] = node{r,d,k+1};
      Q[j++] = node{l,u,k+3};
      Q[j++] = node{r,u,k+4};
      num[i][6] = l;num[i][7] = r;
      num[i][2] = d;num[i][5] = u;
      num[i][8] = n;
   }q <<= 2;
   sort(Q,Q+q,[](node a,node b){return a.x<b.x;});
   int p = 0;
   for(int i=0;i<q;++i){
      while(p<n&&P[p].fi<=Q[i].x)add(P[p++].se);
      num[Q[i].pos/9][Q[i].pos%9] = query(Q[i].y) ;
   }q >>= 2;LL sum = C2(n);
   for(int i=0;i<q;++i){
      LL ans = sum - C2(num[i][2]) - C2(num[i][6]) - C2(num[i][8]-num[i][7]) - C2(num[i][8]-num[i][5]);
      num[i][5] -= num[i][4] ;
      num[i][8] -= num[i][7] + num[i][5];
      ans += C2(num[i][0]) + C2(num[i][6]-num[i][3]) + C2(num[i][2]-num[i][1]) + C2(num[i][8]);
      printf("%I64d\n",ans);
   }
   return 0;
}



阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32570675/article/details/77877476
文章标签: ACM 离线 树状数组
个人分类: 数据结构
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭