1. 程式人生 > >C - Pizza Cutter Gym - 101908C

C - Pizza Cutter Gym - 101908C

傳送門:QAQ

 

 

 

題意:給你一個矩形,給你幾條線,問你矩形被分成了多少區域。

 

思路:離散化一下後,就是經典的樹狀陣列求逆序數,離散化真好,注意會爆(int)。

 

附上程式碼:

#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
struct inst {
	int x;
	int y;
};
int  srt[110000];
int cx[1100000];
inst ax[110000];
const int maxn = 110000;
int n;
long long c[maxn], a[maxn];	
int lowbit(int  x)
{
	return (x)&(-x);
}
void update_onepos(int pos, int x)		
{
	while (pos <= maxn)
	{
		c[pos] += x;
		pos += lowbit(pos);
	}
}
long long getsum_onepos(int pos)		
{
	long long sum = 0;
	while (pos > 0)
	{
		sum += c[pos];
		pos -= lowbit(pos);
	}
	return sum;
}
void build()
{
	memset(c, 0, sizeof(c));
	for (int i = 1; i <= n; i++)
	{
		update_onepos(i, a[i]);
	}
}
int cmp(inst a, inst b) {
	return a.x < b.x;
}
int main(void) {
	int n, m;
	scanf("%d%d", &n, &m);
	int a, b;
	scanf("%d%d", &a, &b);
	for (int i = 0; i < a; i++) {
		scanf("%d%d", &ax[i].x, &ax[i].y);
		srt[i] = ax[i].y;
	}
	build();
	sort(srt, srt + a);
	sort(ax, ax + a, cmp);
	for (int i = 0; i < a; i++) {
		cx[i] = lower_bound(srt, srt + a, ax[i].y) - srt;
	}
	long long sum = 0;
	for (int i = 0; i < a; i++) {
		update_onepos(cx[i]+1,1);
		sum += (i+1 - getsum_onepos(cx[i]+1));
	}
	for (int i = 0; i < b; i++) {
		scanf("%d%d", &ax[i].x, &ax[i].y);
		srt[i] = ax[i].y;
	}
	sort(srt, srt + b);
	sort(ax, ax + b, cmp);
	build();
	for (int i = 0; i < b; i++) {
		cx[i] = lower_bound(srt, srt + b, ax[i].y) - srt;
	}
	for (int i = 0; i < b; i++) {
		update_onepos(cx[i]+1, 1);
		sum += (i+1 - getsum_onepos(cx[i]+1));
	}
	printf("%lld\n", sum + (long long)a*(long long)b + a + b + 1);
	return 0;
}