zoukankan      html  css  js  c++  java
  • HNOI模拟 Day3.23

    一、拓扑(top)
    【 题目描述】:
    给你一个有向二分图,求他的拓扑序列的个数。
    【 输入】:
    第一行两个数 N,M,表示点数和边数。
    接下来 M 行每行两个数 a,b,表示 a 向 b 有一条有向边。
    【 输出】:
    仅一行,为拓扑序列个数 mod 10007。
    【 样例输入】:
    8 10
    1 5
    1 6
    2 6
    2 7
    3 5
    3 8
    3 7
    4 5
    4 7
    4 6
    【 样例输出】:
    972
    【 说明】:
    10%的数据:N≤10;
    30%的数据:N≤20;
    60%的数据:N≤30;
    100%的数据:N≤40;

     
    状压DP
    。。。算了
     
    二、 矩阵 K 小数(mat)
    【 题目描述】
    给你一个 N*N 的矩阵,每次询问一个子矩形的第 K 小数。
    【 输入】
    第一行两个数 N,Q,表示矩阵大小和询问组数;
    接下来 N 行 N 列一共 N*N 个数,表示这个矩阵;
    再接下来 Q 行每行 5 个数描述一个询问:x1,y1,x2,y2,k 表示找到以(x1,y1)为左上角、
    以(x2,y2)为右下角的子矩形中的第 K 小数。
    【 输出】
    对于每组询问输出第 K 小的数。
    【 样例输入】
    2 2
    2 1
    3 4
    1 2 1 2 1
    1 1 2 2 3
    【 样例输出】:
    1 3
    【 说明】:
    矩阵中数字是 109 以内的非负整数;
    20%的数据:N<=100,Q<=1000;
    40%的数据:N<=300,Q<=10000;
    60%的数据:N<=400,Q<=30000;
    100%的数据:N<=500,Q<=60000。

     
    二维树状数组+整体二分
    一开始写来写去,发现莫名其妙WA了,然后学hzwer的,结果发现变得和他一模一样。在神犇XYK帮助下,原来L,R打萎了。。
    改了之后就一直TLE。。
    60,75,80,95
    然后inline,读入优化,剪枝,终于100.。。。太艰辛了
     
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
     
    #define M 60010
    #define N 510
     
    #define lowbit(x) (x & -(x))
     
    struct Node
    {
    int x,y,v;
    }a[N*N];
    int cnt;
     
    bool operator<(Node a,Node b)
    {
    return a.v<b.v;
    }
     
    struct Data
    {
    int x1,y1,x2,y2,k;
    }e[M];
     
    int id[M],f[M],ans[M],tmp[M];
    int g[N][N];
     
    int n,m;
     
    int T;
     
    inline int read()
    {
    int res=0,fh=1;char ch=getchar();
    while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
    if(ch=='-')fh=-1,ch=getchar();
    while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
    return fh*res;
    }
     
    inline void add(int x,int y,int d)
    {
    for (int i=x;i<=n;i+=lowbit(i))
    for (int j=y;j<=n;j+=lowbit(j))
    g[i][j]+=d;
    }
     
    inline int query(int x,int y)
    {
    int zzd(0);
    for (int i=x;i;i-=lowbit(i))
    for (int j=y;j;j-=lowbit(j))
    zzd+=g[i][j];
    return zzd;
    }
     
    inline int query(int k)
    {
    int x1=e[k].x1,y1=e[k].y1,x2=e[k].x2,y2=e[k].y2;
    return query(x2,y2)+query(x1-1,y1-1)-query(x1-1,y2)-query(x2,y1-1);
    }
     
    inline void work(int l,int r,int L,int R)
    {
    if (l>r || L==R)
    return ;
    int mid=(L+R)>>1;
    while (a[T+1].v<=mid && T<cnt)
    add(a[T+1].x,a[T+1].y,1),T++;
    while (a[T].v>mid)
    add(a[T].x,a[T].y,-1),T--;
    int res(0);
    for (int i=l;i<=r;i++)
    {
    if (query(id[i])>e[id[i]].k-1)
    f[i]=1,ans[id[i]]=mid,res++;
    else
    f[i]=0;
    }
    int nowl=l,nowr=l+res;
    for (int i=l;i<=r;i++)
    if (f[i])
    tmp[nowl++]=id[i];
    else
    tmp[nowr++]=id[i];
    for (int i=l;i<=r;i++)
    id[i]=tmp[i];
    if (nowl-l)
    work(l,nowl-1,L,mid);
    if (nowr-l-res)
    work(nowl,nowr-1,mid+1,R);
    }
     
    int main()
    {
    freopen("mat.in","r",stdin);freopen("mat.out","w",stdout);
    n=read(),m=read();
    for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
    {
    cnt++;
    a[cnt].x=i;
    a[cnt].y=j;
    a[cnt].v=read();
    }
    sort(a+1,a+cnt+1);
    for (int i=1;i<=m;i++)
     e[i].x1=read(),e[i].y1=read(),e[i].x2=read(),e[i].y2=read(),e[i].k=read(),id[i]=i;
    work(1,m,0,a[cnt].v+1);
    for (int i=1;i<=m;i++)
    printf("%d ",ans[i]);
    return 0;
    }
     

    三、 最远点(dis)
    【 题目描述】:
    给你一个 N 个点的凸多边形,求离每一个点最远的点。
    【 输入】:
    本题有多组数据,第一行一个数 T,表示数据组数。
    每组数据第一行一个数 N,表示凸多边形点的个数,接下来 N 对数,依次表示 1~N 这
    N 个点的坐标,按照逆时针给出。
    【 输出】:
    对于每组数据输出 N 个数,第 i 个数表示离第 i 个点最远的点的编号,如果有多个最远
    点,输出编号最小的。
    【 样例输入】:
    1 4
    0 0
    1 0
    1 1
    0 1
    【样例输出】:
    3 4 1 2
    【说明】:
    坐标的绝对值在 1e9 以内;
    任意点对距离数值的平方不会超过 long long;
    令 S 为每组数据凸多边形点数之和;
    对于 20%的数据,S<=2000;
    对于 50%的数据,S<=50000;
    对于 100%的数据,S<=500000;
    数据有梯度。

     
    鬼畜分治,考试根本想不到。。
     
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
     
    typedef long long LL;
     
    #define N 500010
     
    struct Node
    {
    int x,y,k;
    }a[N<<1];
     
    int T,n;
     
    int g[N];
     
    LL work(int i, int j)
    {
        return (LL)(a[i].x-a[j].x)*(a[i].x-a[j].x)+(LL)(a[i].y-a[j].y)*(a[i].y-a[j].y);
    }
     
    void work(int l,int r,int L,int R)
    {
    if (l>r)
    return ;
    int m=(l+r)>>1,j;
    LL ans=0;//,nowl=max(m+1,L),nowr=min(m+n,R);
    for (int i=max(m+1,L);i<=min(m+n,R);i++)
    {
    LL tmp=(LL)work(m,i);
    if (tmp>ans)
    ans=tmp,j=i;
    }
    g[m]=a[j].k;
    work(l,m-1,L,j);
    work(m+1,r,j,R);
    }
     
    int main()
    {
    freopen("dis.in","r",stdin);freopen("dis.out","w",stdout);
    scanf("%d",&T);
    while (T--)
    {
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    scanf("%d%d",&a[i].x,&a[i].y),a[i].k=i;
    for (int i=1;i<=n;i++)
    a[i+n]=a[i];
    work(1,n,1,n<<1);
    for (int i=1;i<=n;i++)
    printf("%d ",g[i]);
    }
    return 0;
    }
  • 相关阅读:
    VIJOS-P1340 拯救ice-cream(广搜+优先级队列)
    uva 11754 Code Feat
    uva11426 GCD Extreme(II)
    uvalive 4119 Always an Interger
    POJ 1442 Black Box 优先队列
    2014上海网络赛 HDU 5053 the Sum of Cube
    uvalive 4795 Paperweight
    uvalive 4589 Asteroids
    uvalive 4973 Ardenia
    DP——数字游戏
  • 原文地址:https://www.cnblogs.com/yangjiyuan/p/5320257.html
Copyright © 2011-2022 走看看