zoukankan      html  css  js  c++  java
  • BZOJ2924 [Poi1998]Flat broken lines 【Dilworth定理 + 树状数组】

    题目链接

    BZOJ2924

    题解

    题面有误。。是(45°)

    如果两个点间连线与(x)轴夹角在(45°)以内,那么它们之间连边
    求最小路径覆盖 = 最长反链
    由于(45°)比较难搞,我们利用复数翻转一下,逆时针旋转(45°)
    这样就求一条从左上到右下的最长链
    我们将所有点按(x)排序,令(f[i])表示(i)结尾的最长链
    那么

    [f[i] = max{f[j] + 1} quad [j < i ; y_j > y_i] ]

    离散化一下用树状数组优化

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    #define lbt(x) (x & -x)
    using namespace std;
    const int maxn = 30005,maxm = 100005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    struct point{
    	double x,y; int d;
    }p[maxn];
    inline bool operator <(const point& a,const point& b){
    	return a.x == b.x ? a.d < b.d : a.x < b.x;
    }
    int n,tot;
    double b[maxn];
    inline int getn(double x){return lower_bound(b + 1,b + 1 + tot,x) - b;}
    int s[maxn],f[maxn];
    void modify(int u,int v){while (u) s[u] = max(s[u],v),u -= lbt(u);}
    int query(int u){int re = 0; while (u <= n) re = max(re,s[u]),u += lbt(u); return re;}
    int main(){
    	n = read(); double x,y,s2 = sqrt(2) / 2.0;
    	REP(i,n){
    		x = read(); y = read();
    		p[i] = (point){s2 * (x - y),s2 * (x + y)};
    		b[i] = p[i].y;
    	}
    	sort(b + 1,b + 1 + n); tot = 1;
    	for (int i = 2; i <= n; i++) if (b[i] != b[tot]) b[++tot] = b[i];
    	for (int i = 1; i <= n; i++) p[i].d = getn(p[i].y);
    	sort(p + 1,p + 1 + n); int ans = 0;
    	for (int i = 1; i <= n; i++){
    		f[i] = query(p[i].d + 1) + 1;
    		modify(p[i].d,f[i]);
    		ans = max(ans,f[i]);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    在matlab中出现警告 Function call XX invokes inexact match
    VC2008调用matlab生成的dll和lib
    关于mwArray 的一些资料(一)
    关于C#中的3个timer类(申明是转贴的哦)
    C#教程 PDF
    我也做他个vote machine
    如何用UltraEdit编译C#源程序(再次申明这也是转贴的哦!)
    C#使用技巧调用DLL(还是转贴哦!)
    线程池
    Java web开发中如何自动生成文章html页面
  • 原文地址:https://www.cnblogs.com/Mychael/p/9109971.html
Copyright © 2011-2022 走看看