zoukankan      html  css  js  c++  java
  • BZOJ 1227: [SDOI2009]虔诚的墓主人

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1227

    离散化+树状数组+扫描线。

    如果一个点周围没有树的话,那就没有什么用了。对给的点排序,把x轴离散化掉。

    首先我们要做出每一棵树的l,r,u,d(四个方向上的点的个数)

    然后我们把x轴扔进树状数组维护,对于x坐标相同的两个点,设下面那个点是i,如果这两个点不是紧挨着的话,那么点i的贡献就是

    c[a[i].u][K]*c[a[i].d+1][K]-(ask(a[i].tx)-ask(a[i].tx-1))[之前算过的当然不能重复计算]

    如果两个点的y坐标相同的话,那么答案加上(c[a[i].l+1][K])*(c[a[i+1].r+1][K])*(ask(a[i+1].tx-1)-ask(a[i].tx))
    (代码奇丑。。unique和lower_bound真是个好东西。。。

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define low(x) (x&(-x))
    #define maxn 200500
    #define ll long long
    #define mm 2147483648LL
    using namespace std;
    ll t[maxn],sum[maxn],last[maxn];
    struct data{ll x,y,tx,l,r,u,d,flag;
    }a[maxn];
    ll c[maxn][12],dis[maxn];
    int n,m,w,K,len,y,k;
    ll ans;
    ll read(){
        ll x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    bool cmp(data a,data b){
        if (a.y==b.y) return a.x<b.x;
        else return a.y<b.y;
    }
    void init(){
        c[0][0]=1;
        rep(i,1,100000){
            c[i][0]=1;
            rep(j,1,min(i,10)) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mm;
        }
    }
    void add(int x,ll y){
        while (x<=maxn){
            t[x]=(t[x]+y)%mm;
            x+=low(x);
        }
    }
    ll ask(int x){
        ll ans=0;
        while (x){
            ans=(ans+t[x])%mm;
            x-=low(x);
        }
        return ans;
    }
    int main(){
        n=read(); m=read();
        w=read(); n=w;
        init();
        rep(i,1,w) {
            a[i].x=read(); a[i].y=read();
            dis[i]=a[i].x;
        }
        K=read();
        sort(dis+1,dis+1+w);
        len=unique(dis+1,dis+w+1)-dis-1;
        sort(a+1,a+1+w,cmp);
        y=-1; k=0;
        rep(i,1,w){
            if (a[i].y!=y) {k=0;y=a[i].y;}
            a[i].l=k; k++;
            a[i].tx=lower_bound(dis+1,dis+1+len,a[i].x)-dis;
            if (a[last[a[i].tx]].y+1==a[i].y) a[last[a[i].tx]].flag=1;//上一个点就在它下面
            last[a[i].tx]=i; 
            a[i].d=sum[a[i].tx]; sum[a[i].tx]++;
        }    
        y=-1; k=0;
        down(i,w,1){
            if (a[i].y!=y) {k=0; y=a[i].y;}
            a[i].r=k; k++;
            a[i].u=sum[a[i].tx]-a[i].d-1;
        }
        rep(i,1,w){
            if (a[i].flag!=1) add(a[i].tx,(c[a[i].u][K]*c[a[i].d+1][K]%mm-((ask(a[i].tx)-ask(a[i].tx-1))%mm+mm)%mm)%mm);
            if (a[i].y==a[i+1].y) ans=(ans+(c[a[i].l+1][K])*(c[a[i+1].r+1][K])%mm*(((ask(a[i+1].tx-1)-ask(a[i].tx))%mm+mm)%mm))%mm;
        }
        printf("%lld
    ",ans%mm);
        return 0;
    }
  • 相关阅读:
    第一周、学习嵌入式
    centos7及xfce桌面环境安装,远程工具配置使用方法
    第一次作业
    2018下C语言基础课第1次作业
    第二次作业
    第一次作业
    第0次作业
    博客园第五次作业
    博客园第四次作业
    博客园第三次作业
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5084197.html
Copyright © 2011-2022 走看看