Input file: dull.in
Output file: standard output
Time limit: 9 seconds
Memory limit: 1024 megabytes
Fouad wants to eat a chocolate bar, so he bought a rectangular chocolate bar that has N rows and M
columns of chocolate.
Fouad found that most of the cells in that chocolate bar are dark chocolate except for K cells which are
white chocolate. Now, he wants to eat a prefix sub-grid of the bar. A prefix sub-grid is a rectangular
sub-grid that starts at the first cell (1, 1) and ends at any cell (i, j). Fouad is also wondering how many
perfect prefix sub-grids of the bar. A perfect prefix sub-grid is a one that contains an odd number of white
chocolate cells.
Help Fouad find the number of perfect prefix sub-grids and non-perfect prefix sub-grids.
Input
The first line of the input containing a single integer T specifying the number of test cases.
Each test case begins with a line containing three integers N, M, and K (1 ≤ N, M ≤ 109
, 0 ≤ K ≤ 103
),
in which N and M are the number of rows and columns in the chocolate bar, respectively, and K is the
number of white chocolate cells.
Then K lines follow, each line containing two integers Xi and Yi (1 ≤ Xi ≤ N, 1 ≤ Yi ≤ M), giving the
positions of the white chocolate cells. It is guaranteed that all the given positions are unique.
Output
For each test case, print a single line containing two space-separated integers representing the number of
perfect prefix sub-grids and non-perfect prefix sub-grids, respectively.
Example
dull.in standard output
3
3 3 0
3 3 1
2 2
5 5 5
1 5
2 1
3 3
4 2
5 4
0 9
4 5
14 11
Note
In the second test case, the chocolate bar can be represented as follows:
ddd
dwd
ddd
in which ‘d’ represents dark chocolate cells while ‘w’ represents white chocolate cells. There are four perfect
prefix sub-grids that end at cells: (2, 2), (2, 3), (3, 2), and (3, 3).
题意:
给你矩形坐标和n个点的坐标,问你有多少以1,1为起始的矩形包含奇数个点。
题解:
可以看到数据范围很小,那么可以用n^2来做,首先设立实点和虚点,比如1,1 和2,2,实点就是这两个,虚点就是1,2和2,1。因为这样能包含所有情况,在x或者y不越过任意虚点的时候答案是不会变的。在求出当前点为右上角的矩形的时候,找出下一个x和y表示这种状态最大能维持到哪个矩形,1,1 3,1的时候,在y=1时x从1到(3-1)都是一个状态。在x和y是边界的时候,就是说x在右边没有点,y上面没有点时特判。首先离散化,否则会出错,比如说x的集合是1,1,3的时候,不离散化得出的答案会被重复算。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5e3+5;
int num[N];
int lowbit(int x)
{
return x&(-x);
}
void add(int x)
{
for(int i=x;i<N;i+=lowbit(i))
num[i]++;
}
int query(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i))
ans+=num[i];
return ans;
}
int x[N],y[N],lsx[N],lsy[N],vis[N][N];
int main()
{
freopen("dull.in","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
int n,m,k;
ll ans=0;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
scanf("%d%d",&x[i],&y[i]),lsx[i]=x[i],lsy[i]=y[i];
sort(lsx+1,lsx+1+k),sort(lsy+1,lsy+1+k);
int allx,ally;
allx=unique(lsx+1,lsx+1+k)-lsx-1;
ally=unique(lsy+1,lsy+1+k)-lsy-1;
for(int i=1;i<=k;i++)
{
x[i]=lower_bound(lsx+1,lsx+1+allx,x[i])-lsx;
y[i]=lower_bound(lsy+1,lsy+1+ally,y[i])-lsy;
vis[x[i]][y[i]]=1;
}
sort(x+1,x+k+1),sort(y+1,y+1+k);
allx=unique(x+1,x+k+1)-x-1;
ally=unique(y+1,y+1+k)-y-1;
for(int i=1;i<=allx;i++)
{
for(int j=1;j<=ally;j++)
{
if(vis[x[i]][y[j]])
add(y[j]);
int sum=query(y[j]);
if(sum%2)
{
if(i==allx&&j==ally)
ans+=(ll)(n-lsx[x[i]]+1)*(m-lsy[y[j]]+1);
else if(i==allx)
ans+=(ll)(n-lsx[x[i]]+1)*(lsy[y[j+1]]-lsy[y[j]]);
else if(j==ally)
ans+=(ll)(lsx[x[i+1]]-lsx[x[i]])*(m-lsy[y[j]]+1);
else
ans+=(ll)(lsx[x[i+1]]-lsx[x[i]])*(lsy[y[j+1]]-lsy[y[j]]);
}
}
}
printf("%lld %lld\n",ans,(ll)n*m-ans);
}
return 0;
}