终于到达了这次选拔赛的最后一题,想必你已经厌倦了小蓝和小白的故事,为了回馈各位比赛选手,此题的主角是贯穿这次比赛的关键人物——小蓝的好友。
Problem 2658. – [Zjoi2012]小蓝的好友(mrx)
【数据范围】
对于100%的数据,R,C<=40000,N<=100000,资源点的位置两两不同,且位置为随机生成。
刚开始看到这题..什么思路都没有,只有打暴力的想法,不过后来换了个思路,就是全集减去不包含任何一个点的矩形个数。假如一个空白矩阵的长为a,宽为b,那么中间矩形的个数就是 C2a+1∗C2b+1=a∗(a+1)/2∗b∗(b+1)/2 C a + 1 2 ∗ C b + 1 2 = a ∗ ( a + 1 ) / 2 ∗ b ∗ ( b + 1 ) / 2 ,想到这里之后,我们就可以很自然可以想到记录每个点向上可以延伸的最大距离,和这个矩阵的最大宽度,那就可以做完这道题了。
至于如何找到这个矩形,我们可以通过treap建立一颗笛卡尔树,每个点存储这个点向上的最大高度h,和这个点可以向左右延伸的最大宽度sz(因为是笛卡尔树所以他的子树size就是最大宽度),还有这个点的ans(不包括这个点的它的子树的贡献)。那么一个点对他的父节点的贡献就是 sz[o]+(sz[o]+1)∗(h[o]−h[f[o]])2 s z [ o ] + ( s z [ o ] + 1 ) ∗ ( h [ o ] − h [ f [ o ] ] ) 2 了,于是答案就很明显了。
#pragma GCC optimize(3)
#include
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
const int maxn=100010;
struct Treap {
int son[maxn][2],tag[maxn],rt;
ll ans[maxn],sz[maxn],h[maxn];
inline void add(int o,int x) {
h[o]+=x;
tag[o]+=x;
}
inline ll calc(ll x) {
return x*(x+1)/2;
}
inline void update(int o) {
sz[o]=1,ans[o]=0;
int x=son[o][0],y=son[o][1];
if(x) {
sz[o]+=sz[x];
ans[o]+=ans[x]+calc(sz[x])*(h[x]-h[o]);
}
if(y) {
sz[o]+=sz[y];
ans[o]+=ans[y]+calc(sz[y])*(h[y]-h[o]);
}
}
inline void pushdown(int o) {
if(tag[o]) {
if(son[o][0])
add(son[o][0],tag[o]);
if(son[o][1])
add(son[o][1],tag[o]);
update(o);
tag[o]=0;
}
}
inline void build(int &o,int l,int r) {
if(l>r) {
o=0;
return;
}
int mid=(l+r)/2;
o=mid;
build(son[o][0],l,mid-1);
build(son[o][1],mid+1,r);
update(o);
}
inline void rotate(int &o,int z) {
int y=son[o][z];
son[o][z]=son[y][z^1];
son[y][z^1]=o;
update(o),update(y);
o=y;
}
inline void modify(int &o,int y) {
pushdown(o);
if(y==sz[son[o][0]]+1) {
h[o]=0;
update(o);
return;
}
if(y0]]+1) {
modify(son[o][0],y);
rotate(o,0);
}
else {
modify(son[o][1],y-sz[son[o][0]]-1);
rotate(o,1);
}
}
}vvq;
int n,m,c;
vector<int>G[maxn];
ll ans;
int main() {
read(n),read(m),read(c);
for(int i=1,u,v;i<=c;i++) {
read(u),read(v);
G[u].push_back(v);
}
ans=vvq.calc(n)*vvq.calc(m);
vvq.build(vvq.rt,1,m);
for(int i=1;i<=n;i++) {
vvq.add(vvq.rt,1);
for(unsigned j=0;jprintf("%lld\n",ans);
}