zoukankan      html  css  js  c++  java
  • BZOJ3688: 折线统计

    题解:

    令f[i][j][0/1]表示前i个数有j段,最后一段是下降/上升的方案数

    很容易列出状态转移方程(已按x轴排序)

    f[i][j][0]=sigma(f[k][j][0]+f[k][j-1][1])(k<i&&a[k]>a[i])

    f[i][j][1]=sigma(f[k][j][1]+f[k][j-1][1])(k<i&&a[k]<a[i])

    很明显可以用树状数组优化。

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 100000+5
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
    23 #define mod 100007
    24 using namespace std;
    25 inline int read()
    26 {
    27     int x=0,f=1;char ch=getchar();
    28     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    29     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    30     return x*f;
    31 }
    32 int n,m,b[maxn];
    33 struct rec{int x,y;}a[maxn];
    34 inline bool cmp(rec a,rec b){return a.x<b.x;}
    35 inline bool cmp1(int i,int j){return a[i].y<a[j].y;}
    36 struct bit
    37 {
    38     int s[maxn];
    39     inline void add(int x,int y)
    40     {
    41         y=(y%mod+mod)%mod;
    42         for(;x<=n;x+=x&(-x))(s[x]+=y)%=mod;
    43     }
    44     inline int sum(int x)
    45     {
    46         int t=0;
    47         for(;x;x-=x&(-x))(t+=s[x])%=mod;
    48         return t;
    49     }
    50 }t[11][2];
    51 int main()
    52 {
    53     freopen("input.txt","r",stdin);
    54     freopen("output.txt","w",stdout);
    55     n=read();m=read();
    56     for1(i,n)a[i].x=read(),a[i].y=read();
    57     sort(a+1,a+n+1,cmp);
    58     for1(i,n)b[i]=i;
    59     sort(b+1,b+n+1,cmp1);
    60     for1(i,n)a[b[i]].y=i;
    61     for1(i,n)
    62     {
    63      t[0][0].add(a[i].y,1);t[0][1].add(a[i].y,1);
    64      for1(j,m)
    65       {
    66            t[j][0].add(a[i].y,t[j][0].sum(n)-t[j][0].sum(a[i].y)+t[j-1][1].sum(n)-t[j-1][1].sum(a[i].y));
    67            t[j][1].add(a[i].y,t[j][1].sum(a[i].y-1)+t[j-1][0].sum(a[i].y-1));
    68       }
    69     }
    70     printf("%d
    ",(t[m][0].sum(n)+t[m][1].sum(n))%mod);    
    71     return 0;
    72 }
    View Code

    3688: 折线统计

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 60  Solved: 37
    [Submit][Status]

    Description

    二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升、下降的折线,设其数量为f(S)。如下图中,1->2,2->3,3->5,5->6(数字为下图中从左到右的点编号),将折线分为了4部分,每部分连续上升、下降。
     
    现给定k,求满足f(S) = k的S集合个数。

    Input

    第一行两个整数n和k,以下n行每行两个数(xi, yi)表示第i个点的坐标。所有点的坐标值都在[1, 100000]内,且不存在两个点,x坐标值相等或y坐标值相等

    Output

    输出满足要求的方案总数 mod 100007的结果

    Sample Input

    5 1
    5 5
    3 2
    4 4
    2 3
    1 1

    Sample Output

    19

    HINT

    对于100%的数据,n <= 50000,0 < k <= 10

  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4176053.html
Copyright © 2011-2022 走看看