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

      终于填上了这个万年巨坑....从初二的时候就听说过这题...然后一直不敢写QAQ

      现在感觉也不是很烦(然而我还是写麻烦了

      离散化一波,预处理出组合数什么的。。

      要维护对于当前行,每列上方和下方节点凑出合法方案的个数。

      然后对于当前行上两棵相邻的常青树,求一下左边、右边合法方案数,乘上中间空的列的合法方案总数就好了。

      单点修改,区间查询。。我竟然跑去写线段树...懒得改了。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ui unsigned int
     6 using namespace std;
     7 const int maxn=100233,mxnode=maxn<<1;
     8 struct zs{int v,id;}X[maxn],Y[maxn];
     9 struct poi{int x,y;}a[maxn];
    10 int lc[mxnode],rc[mxnode],num1[mxnode],num2[mxnode],tot;
    11 int mp[maxn],st[maxn],top;
    12 ui sm[mxnode],ans,SM,c[maxn][11];
    13 int i,j,k,n,m,kk,L,R,P;
    14   
    15   
    16 int ra,fh;char rx;
    17 inline int read(){
    18     rx=getchar(),ra=0,fh=1;
    19     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
    20     if(rx=='-')fh=-1,rx=getchar();
    21     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
    22 }
    23 void build(int a,int b){
    24     int x=++tot;
    25     if(a==b){num2[x]=mp[a];return;}
    26     int mid=a+b>>1;
    27     lc[x]=tot+1,build(a,mid),rc[x]=tot+1,build(mid+1,b);
    28 }
    29 void change(int x,int a,int b){
    30     if(a==b){
    31         num1[x]++,num2[x]--,sm[x]=c[num1[x]][kk]*c[num2[x]][kk];
    32         return;
    33     }
    34     int mid=a+b>>1;
    35     if(P<=mid)change(lc[x],a,mid);else change(rc[x],mid+1,b);
    36     sm[x]=sm[lc[x]]+sm[rc[x]];
    37 }
    38 void query(int x,int a,int b){
    39     if(L<=a&&R>=b){
    40         SM+=sm[x];return;
    41     }
    42     int mid=a+b>>1;
    43     if(L<=mid)query(lc[x],a,mid);
    44     if(R>mid)query(rc[x],mid+1,b);
    45 }
    46  
    47  
    48 bool cmp(zs a,zs b){return a.v<b.v;}
    49 bool cmpa(poi a,poi b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    50 int main(){
    51     n=read(),m=read();
    52     n=read();
    53     for(i=1;i<=n;i++)X[i].v=read(),Y[i].v=read(),X[i].id=Y[i].id=i;
    54     kk=read();
    55     for(i=0;i<=n;i++)c[i][0]=1;
    56     for(i=1;i<=n;i++)for(j=1;j<=kk;j++)c[i][j]=c[i-1][j]+c[i-1][j-1];
    57 //  for(i=1;i<=n;i++)printf("C(%d %d)  %u
    ",i,kk,c[i][kk]);return 233;
    58      
    59     sort(X+1,X+1+n,cmp),sort(Y+1,Y+1+n,cmp);int cntx=0,cnty=0;
    60     for(i=1;i<=n;a[X[i].id].x=cntx,i++)
    61         if(X[i].v!=X[i-1].v||i==1)cntx++;
    62     for(i=1;i<=n;a[Y[i].id].y=cnty,mp[cnty]++,i++)
    63         if(Y[i].v!=Y[i-1].v||i==1)cnty++;
    64     sort(a+1,a+1+n,cmpa);
    65     build(1,cnty);
    66      
    67     for(i=1;i<=n;){
    68         int r=i-1,top=0;
    69         while(r<n&&a[r+1].x==a[i].x)r++,st[++top]=P=a[r].y,change(1,1,cnty);//,printf("   %d",P);puts("");
    70         if(top>=(kk<<1))
    71         for(j=kk;j<=top-kk;j++)if(st[j]+1<st[j+1])
    72             SM=0,L=st[j]+1,R=st[j+1]-1,query(1,1,cnty),
    73             ans+=SM*c[j][kk]*c[top-j][kk];
    74         i=r+1;
    75     }
    76     printf("%d
    ",ans<<1>>1);
    77 }
    View Code
  • 相关阅读:
    sql查询自然数判断
    esayswool_admin的3个坑
    debian安装easyswoole
    微软浏览器冲浪小游戏
    php程序的安装和composer
    图片搬运工
    热血高校这部电影中的内含文化
    Google日本語入力的使用方法,基本的快捷键。
    PHP截取两个指定字符中间的字符
    php去除字符串中的HTML标签
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5645070.html
Copyright © 2011-2022 走看看