zoukankan      html  css  js  c++  java
  • 清北合肥day2-day5

    day2:215
    这一天的题目相对比较模板化
    t1:50
    看错了数据范围
    求n个点到给出的点哈夫曼距离的最小值
    我想到的是一种非常zz的做法
    我们二分答案,然后判断是否在这个距离内有点
    但是这样前缀和不是很好维护
    于是我们利用哈夫曼距离和切比雪夫距离的转化
    (x+y,x-y)
    然后就变成了简单的二维前缀和
    另外坐标有负数,所以要都加一个值
    其实有更简单的做法
    直接做多源最短路就可以了
    t2:100
    首先我们可以按照ai排序
    然后动态维护最小生成树(支持加边)
    这个本身是lct裸题
    但是因为这题目里有点数限制
    所以我们可以暴力访问两点之间的路径
    怎么找路径呢?(直接dfs就可以了)

    t3:65

    65就是个基本的暴力(因为没有时间就没有搞正解了)

    首先我们要把撤销操作给搞掉

    其实就是倒着访问搜索树

    然后就变成了维护颜色

    然后我们发现那个操作是等价于对二分图的点搞

    所以按照行+列分类

    然后问题就变成了子矩形覆盖查询最终颜色的问题

    注意这个东西是不能直接树套树维护的

    因为并不能保证先后顺序

    可行的树套树维护方案是

    我们倒着做,那么每个点被第一次覆盖就是最终颜色

    于是这个是经典的线段树问题了,记录区间内是否有没有覆盖颜色的地方

    复杂度n^2log^2

    另外题解给出了并查集的维护方法

    考虑如果是序列问题

    维护每一个下一个没有凃颜色的地方

    本质和树套树是一样的

    然后推广到二维就直接暴力推广

    复杂度(nq+n^2)*logn

    下面这个是代码

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define mid ((h+t)>>1)
    char c;
    const int N=510;
    const int N2=2e6;
    bool f[N][N],ans[N2];
    bitset<501> g[2][N][N];
    struct re{
        int a,b,c,d,e;
    }a[N2],b[N2];
    int n,m;
    void fz(int h,int t,int h1,int t1)
    {
        dep(i,mid,h)
          dep(j,m,1)
          {
              g[0][i][j]=0;
              if (f[i][j])
              {
                if (i==mid) g[0][i][j][j]=1;
                if (j+1<=m&&f[i][j+1]) g[0][i][j]|=g[0][i][j+1];
                if (i+1<=mid&&f[i+1][j]) g[0][i][j]|=g[0][i+1][j];
            }
          }
        rep(i,mid,t)
          rep(j,1,m)
          {
            g[1][i][j]=0;
            if (f[i][j])
            {
              if (i==mid) g[1][i][j][j]=1;
              if (j-1>=1&&f[i][j-1]) g[1][i][j]|=g[1][i][j-1];
              if (i-1>=mid&&f[i-1][j]) g[1][i][j]|=g[1][i-1][j];
            }
          }
        int h2=h1-1,t2=t1+1;
        rep(i,h1,t1)
        {
            if (a[i].a<=mid&&a[i].c>=mid)
              ans[a[i].e]=(g[0][a[i].a][a[i].b]&g[1][a[i].c][a[i].d]).any();
            else if (a[i].c<mid) b[++h2]=a[i];
            else b[--t2]=a[i];
        }
        rep(i,h1,h2) a[i]=b[i];
        if (h<=mid-1) fz(h,mid-1,h1,h2);
        rep(i,t2,t1) a[i]=b[i];
        if (mid+1<=t) fz(mid+1,t,t2,t1);
    }
    int main()
    {
        freopen("boardgame.in","r",stdin);
        freopen("boardgame.out","w",stdout);
        ios::sync_with_stdio(false);
        cin>>n>>m;
        rep(i,1,n)
        {
            rep(j,1,m)
            {
              cin>>c;
              if (c=='.') f[i][j]=1;
              else f[i][j]=0;
            }
        }
        int k;
        cin>>k;
        rep(i,1,k)
        {
            int x,y,x1,y1;
            cin>>x>>y>>x1>>y1;
            a[i].a=x; a[i].b=y; a[i].c=x1; a[i].d=y1; a[i].e=i;
        }
        fz(1,n,1,k);
        rep(i,1,k)
          if (ans[i]) printf("Yes
    ");
          else printf("No
    "); 
        return 0;
    }

     其实我们有更优秀的方法来解决大范围问题

    矩形问题还是应该多考虑一下扫描线

    于是现在我们要维护的其实是每个点出现颜色的最晚的值

    这个我们可以线段树套平衡树来维护

    (注意具体的我们要标记永久化来维护,因为这个标记是不支持down的)

    于是假设不是要求出所有位置的颜色

    我们的复杂度就是qlog^2了

    相比之前的有很大进展

    另外要注意一下这个东西不能用kd-tree来做

    我写完才发现很有问题。。

    kd-tree支持的操作是,修改一定要对在kd-tree上的点进行修改

    也就是说kd-tree维护的是单点修改区间查询操作

    而这道题如果要维护就得把所有点加入

    而kd-tree的最坏复杂度是sqrt(n) 此时n=n^2

    所以退化成暴

    day3:280

    我感觉是非常zz的一天

    考完???为什么两道线段树 然后正解都不需要这个东西

    第一题瞎模拟就不说了

    第二题其实很简单,想复杂了

    支持三个操作

    1.在某一个邮箱放一封新的信

    2.删除某个邮箱里的所有信

    3.删除前k封信

    我都已经忘记我怎么想出来这么zz的线段树了

    正解就是对于删前k封信这个操作记录一下

    然后对删某个邮箱里的信暴力进行(先把那个标记进行一下)

    因为每个信最多被删一次,所以就是O(n)的了

    然后写线段树的时候

    我写了个dfs函数,当f[x]==0的时候才停止

    也就是说查到了h==t的点的儿子

    于是造成了需要8倍空间的事情

    而我只写了4倍空间 就炸了20分

    第三题 还是比较水的

    我们枚举它最终降到几分

    那么比它低的肯定就比它低了

    对于比它高的,我们肯定要让比较容易翻车的先翻车

    然后 我考场上想的是

    插入到线段树里,用线段树二分来做这个东西

    虽然复杂度和正解是一样的nlogn 但现在想想非常zz

    ·

  • 相关阅读:
    20165226 2017-2018-4 《Java程序设计》第8周学习总结
    20165226第二次实验
    结对编程练习-四则运算(第一周)
    20165226 2017-2018-4 《Java程序设计》第7周学习总结
    20165226 2017-2018-4 《Java程序设计》第6周学习总结
    实验一 Java开发环境的熟悉
    20165226 2017-2018-3 《Java程序设计》第5学习总结
    第四周课下作业
    第4周学习总结
    第三周学习
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9745569.html
Copyright © 2011-2022 走看看