BZOJ 1227 虔诚的墓主人

Posted on 2016-10-16 17:01  ziliuziliu  阅读(135)  评论(0编辑  收藏  举报

离散化扫描线搞搞。。。好像要个o(1)快速乘什么的。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100500
#define mod 2147483648LL
using namespace std;
struct pnt
{
    long long x,y;
}p[maxn];
long long n,m,w,x,y,k,c[maxn][12],hash[maxn],top=0,t[maxn],cnt[maxn],tmp[maxn];
long long mul(long long a,long long b)
{
    long long d=(long long)floor(a*(long double)b/mod+0.5);
    long long ret=a*b-d*mod;
    if (ret<0) ret+=mod;
    return ret;
}
bool cmp(pnt x,pnt y)
{
    if (x.y!=y.y) return x.y<y.y;
    return x.x<y.x;
}
void get_table()
{
    c[0][0]=1;
    for (long long i=1;i<=w;i++)
    {
        c[i][0]=1;
        for (long long j=1;j<=min(k,i);j++)
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
    }
}
long long find(long long x)
{
    return lower_bound(hash+1,hash+top+1,x)-hash;
}
long long lowbit(long long x)
{
    return (x&(-x));
}
void modify(long long x,long long val)
{
    for (long long i=x;i<=top;i+=lowbit(i))
        t[i]=(t[i]+val)%mod;
}
long long ask(long long x)
{
    long long ret=0;
    for (long long i=x;i>=1;i-=lowbit(i))
        ret=(ret+t[i])%mod;
    return ret;
}
void get_ans()
{
    long long ans=0;long long ret;
    long long l=1,r=1;
    while (l<=w)
    {
        r=l;
        while ((p[r+1].y==p[l].y) && (r+1<=w)) r++;
        ret=r-l+1;
        for (long long i=l+1;i<=r;i++)
            ans=(ans+mul(mul(c[i-l][k],c[ret-i+l][k]),(ask(find(p[i].x)-1)-ask(find(p[i-1].x)))%mod)%mod)%mod;
        for (long long i=l;i<=r;i++)
        {
            long long tr=find(p[i].x);
            tmp[tr]++;
            long long val=ask(tr)-ask(tr-1);
            modify(tr,-val);modify(tr,mul(c[tmp[tr]][k],c[cnt[tr]-tmp[tr]][k]));
        }
        l=r+1;
    }
    printf("%lld\n",ans);
}
int main()
{
    scanf("%lld%lld",&n,&m);
    scanf("%lld",&w);
    for (long long i=1;i<=w;i++)
    {
        scanf("%lld%lld",&p[i].x,&p[i].y);
        hash[++top]=p[i].x;
    }
    scanf("%lld",&k);
    get_table();
    sort(hash+1,hash+top+1);top=unique(hash+1,hash+top+1)-hash-1;
    sort(p+1,p+w+1,cmp);
    for (long long i=1;i<=w;i++) cnt[find(p[i].x)]++;
    get_ans();
    return 0;
}