zoukankan      html  css  js  c++  java
  • 「训练日志16」 8.11 下坠

    T1 入阵曲

      不算很水,看题解后明白不叫水题。

      为什么你想不到正解,这需要你好好想想。

      $n^4$暴力很好想,傻逼二维前缀和完事儿了。然后就是优化了。

      怎么优化?题目的数据范围显然是$n^3$的复杂度,朝着这个方向想,考虑我们可以删掉哪一维呢?

      首先,我们必须要卡出来一段区间,没有固定区间怎么都不行,在有,$++ans$是肯定不行的,我们一定要找出来规律。

      这道题有一个性质,两个数模k相同,那他们相减一定是k的倍数。根据这个性质,我们维护一个桶,记录当前区间总共有模k意义下这个数有多少个,枚举每一列,他们的方案数就是他们可以组成的相同余数的对数,转移即可。

      注意一下,当$x%k==0$时,本身已经和k整除,特判一下,注意$++$顺序。

      小弟不才。

     1 #include<cstdio>
     2 #define LL long long
     3 #define HZOI std
     4 using namespace HZOI;
     5 int n,m,k,ooo;
     6 int rst[1000003],vis[1000003],tail;
     7 LL ans,sm[505][505],t[1000003];
     8 inline int read();
     9 int main()
    10 {
    11     n=read(),m=read(),k=read();
    12     for (int i=1; i<=n; ++i)
    13         for (int j=1; j<=m; ++j)
    14             sm[i][j]=sm[i-1][j]+sm[i][j-1]-sm[i-1][j-1]+read();
    15     for (int i=1; i<=n; ++i)
    16         for (int j=i; j<=n; ++j)
    17         {
    18             for (int g=1; g<=m; ++g)
    19             {
    20                 ooo=(sm[j][g]-sm[i-1][g]+k)%k;
    21                 if (!ooo) ans+=(++t[ooo]);
    22                 else ans+=(t[ooo]++);
    23                 if (!vis[ooo]) vis[ooo]=1,rst[++tail]=ooo;
    24             }
    25             while (tail>0) vis[rst[tail]]=0,t[rst[tail--]]=0;
    26         }
    27     printf("%lld
    ",ans);
    28 }
    29 inline int read()
    30 {
    31     int nn=0; char cc=getchar();
    32     while (cc<'0' or cc>'9') cc=getchar();
    33     while (cc>='0' and cc<='9') nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar();
    34     return nn;
    35 }
    入阵曲

     

    T2 将军令

      牛逼题,联赛难度,可是我不会做。

      又是贪心题,从儿子开始找,找离他最远的一个可以控制他的祖先,给他点亮,$Dfs$一下,这题就没了。

      这个证明吧,我要找更高的父亲,他能控制的点只多不少,只要我找到了一个最深的叶子节点,往上回溯,到达的最远的父亲的子树一定全部被控制,然后贪就可以了。

      我用的$Dfs$,转移起来很麻烦,也比较难理解,$Bfs$的方法还是$three_D$神仙教给我的。

      主要需要维护好几个东西

    1. 最深的没有被控制的儿子的$depth$ $di$
    2. 向上回溯第一个不能被控制的距离(为负值)$minn$
    3. 向下需要控制的距离$maxx$
    4. 最深儿子$dimax$

      其实最主要的还是$di$,其他三个信息的维护,大部分都是该变量的参与,转移过程很麻烦,兄弟祖先的情况需要很多特判。

      小弟不才。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #define HZOI std
     4 using namespace HZOI;
     5 const int N=1e6+3;
     6 int n,m,opt,ans;
     7 int tt,first[N],vv[N<<1],nx[N<<1];
     8 int vis[N],di;
     9 void Dfs(int ,int );
    10 inline void Add(int ,int );
    11 inline int read();
    12 inline int max(int a,int b) {return a>b?a:b;}
    13 inline int min(int a,int b) {return a<b?a:b;}
    14 int main()
    15 {
    16     n=read(),m=read(),opt=read();
    17     for (int i=1,x,y; i<n; ++i)
    18     {
    19         x=read(),y=read();
    20         Add(x,y); Add(y,x);
    21     }
    22     Dfs(1,1);
    23     printf("%d
    ",ans);
    24     return 0;
    25 }
    26 void Dfs(int k,int depth)
    27 {
    28     vis[k]=1;
    29     di=max(depth,di);
    30     int maxdi=depth;
    31     int minn=0x3f3f3f3f,maxx=0;
    32     for (int i=first[k]; i; i=nx[i])
    33     {
    34         int ver=vv[i];
    35         if (vis[ver]) continue;
    36         Dfs(ver,depth+1);
    37         maxx=max(di-depth,maxx),
    38         minn=min(di-depth,minn);
    39         maxdi=max(di,maxdi);
    40     }
    41     if (maxx+minn<0) {di=depth+minn;return ;}
    42     if (k^1 and maxx>=m) {++ans,di=depth-m-1;return ;}
    43     if (k==1 and maxx+minn>=0) {++ans;return ;}
    44     di=maxdi;
    45 }
    46 inline void Add(int u,int v)
    47 {
    48     vv[++tt]=v,nx[tt]=first[u],first[u]=tt;
    49 }
    50 inline int read()
    51 {
    52     int nn=0; char cc=getchar();
    53     while (cc<'0' or cc>'9') cc=getchar();
    54     while (cc>='0' and cc<='9') nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar();
    55     return nn;
    56 }
    将军令

      

  • 相关阅读:
    c# 解决读取Excel混合文本类型,数据读取失败的解决方法
    c#中的常用ToString()方法总结
    vsts
    RSA加密解密
    odbc连接数据库
    SerialPort
    C# Winform下载文件并显示进度条
    c# 面试题
    SQL Server 存储过程
    mysql 事务处理
  • 原文地址:https://www.cnblogs.com/LH-Xuanluo/p/11337596.html
Copyright © 2011-2022 走看看