zoukankan      html  css  js  c++  java
  • bzoj4059 [Cerc2012]Non-boring sequences && bzoj5200 [NWERC2017]Factor-Free Tree

    https://konnyakuxzy.github.io/BZPRO/JudgeOnline/4059.html

    https://cn.vjudge.net/problem/Gym-100624D

    根本不会。。。

    似乎有很高妙的分治做法啊!https://www.cnblogs.com/forever97/p/bzoj4059.html

    就是说,如果当前区间为[l,r],存在一个i满足pre[i]<l&&nxt[i]>r,那么任意一个[l,r]的子区间,只要包含i点就不无聊,因此只需要再检验[l,i-1]和[i+1,r]即可

    复杂度n*log就是因为倒过来就是启发式合并的过程。。。

    以前代码很奇怪不知道怎么回事也A掉了。。。

    if(i==j)    break;
    i++;
    if(pre[i]<l&&nxt[i]>r)    return solve(l,i-1)&&solve(i+1,r);
    if(i==j)    break;
    j--;
    if(pre[j]<l&&nxt[j]>r)    return solve(l,j-1)&&solve(j+1,r);
    View Code
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #include<map>
     6 using namespace std;
     7 #define fi first
     8 #define se second
     9 #define mp make_pair
    10 #define pb push_back
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 typedef pair<int,int> pii;
    14 int n,T,a[200100];
    15 int pre[200100],nxt[200100];
    16 map<int,int> ma;
    17 bool solve(int l,int r)
    18 {
    19     if(l>=r)    return 1;
    20     int i,j;
    21     for(i=l,j=r;;)
    22     {
    23         if(pre[i]<l&&nxt[i]>r)    return solve(l,i-1)&&solve(i+1,r);
    24         i++;
    25         if(i>j)    break;
    26         if(pre[j]<l&&nxt[j]>r)    return solve(l,j-1)&&solve(j+1,r);
    27         j--;
    28         if(i>j)    break;
    29     }
    30     return 0;
    31 }
    32 int main()
    33 {
    34     int i;
    35     scanf("%d",&T);
    36     while(T--)
    37     {
    38         scanf("%d",&n);
    39         for(i=1;i<=n;i++)    scanf("%d",&a[i]);
    40         ma.clear();
    41         for(i=1;i<=n;i++)
    42         {
    43             pre[i]=ma.count(a[i])?ma[a[i]]:0;
    44             ma[a[i]]=i;
    45         }
    46         ma.clear();
    47         for(i=n;i>=1;i--)
    48         {
    49             nxt[i]=ma.count(a[i])?ma[a[i]]:n+1;
    50             ma[a[i]]=i;
    51         }
    52         puts(solve(1,n)?"non-boring":"boring");
    53     }
    54     return 0;
    55 }

    也有很高妙的扫描线做法啊!https://blog.csdn.net/PoPoQQQ/article/details/46380617


    https://konnyakuxzy.github.io/BZPRO/JudgeOnline/5200.html

    https://cn.vjudge.net/problem/Gym-101623F

    做法跟上面那题几乎是一样的

    仍然不会。。。

    做法是类似的,卡在”区间内有多个可作为根的位置时,如何选择“上了

    上网查了一下,发现怎样选择并不会影响答案。。。

    证明很简单:假设已经得到了区间内一组以a为根的合法解,b也是一个合法根,直接把这棵树的根改为b,那么显然只有a到b的链上的所有边的两个端点的父亲-祖先关系反了一下,显然这条链上端点的值两两互质,因此这样子换根之后也是合法解

    还有一点:我自己想的是每次分治直接分解质因数然后怎么怎么样,很慢,可能被卡常(质因数分解n^(1/4)吧?)

    然而,可以直接线筛出1e7内每个数的最小质因子。。。然后分解质因子复杂度只要一个log

    而且,只需要预处理每个数的上一个和下一个与其不互质的数位置即可。。。感觉常数要小不少啊

    错误记录:

    1.已经发现了需要单独记录f[t],然后while才能除以的是同一个数(就是需要69行),但是只改了一半(没改81行)

    2.LA上有多组数据,但是我没有完整地清空(WA了很多发,包括61行,87行(需要fa[..]=0))

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 #include<map>
     6 using namespace std;
     7 #define fi first
     8 #define se second
     9 #define mp make_pair
    10 #define pb push_back
    11 typedef long long ll;
    12 typedef unsigned long long ull;
    13 typedef pair<int,int> pii;
    14 bool nprime[10000010];
    15 int prime[1000100],len,f[10000010];
    16 int n,a[1001000];
    17 int pre[1001000],nxt[1001000];
    18 map<int,int> ma;
    19 bool fl;
    20 int fa[1001000];
    21 int solve(int l,int r)
    22 {
    23     if(l>r)    return 0;
    24     if(l==r)    return l;
    25     int i,j;
    26     for(i=l,j=r;;)
    27     {
    28         if(pre[i]<l&&nxt[i]>r)
    29         {
    30             fa[solve(l,i-1)]=i;
    31             fa[solve(i+1,r)]=i;
    32             return i;
    33         }
    34         i++;
    35         if(i>j)    break;
    36         if(pre[j]<l&&nxt[j]>r)
    37         {
    38             fa[solve(l,j-1)]=j;
    39             fa[solve(j+1,r)]=j;
    40             return j;
    41         }
    42         j--;
    43         if(i>j)    break;
    44     }
    45     fl=1;
    46     return 0;
    47 }
    48 int main()
    49 {
    50     int i,j,t,q;
    51     for(i=2;i<=10000000;i++)
    52     {
    53         if(!nprime[i])    prime[++len]=i,f[i]=i;
    54         for(j=1;j<=len&&i*prime[j]<=10000000;j++)
    55         {
    56             nprime[i*prime[j]]=1;f[i*prime[j]]=prime[j];
    57             if(i%prime[j]==0)    break;
    58         }
    59     }
    60     while(scanf("%d",&n)==1){
    61     fl=0;
    62     for(i=1;i<=n;i++)    scanf("%d",&a[i]);
    63     ma.clear();
    64     for(i=1;i<=n;i++)
    65     {
    66         t=a[i];pre[i]=0;
    67         while(t!=1)
    68         {
    69             q=f[t];
    70             pre[i]=max(pre[i],ma.count(q)?ma[q]:0);
    71             ma[q]=i;
    72             while(t%q==0)    t/=q;
    73         }
    74     }
    75     ma.clear();
    76     for(i=n;i>=1;i--)
    77     {
    78         t=a[i];nxt[i]=n+1;
    79         while(t!=1)
    80         {
    81             q=f[t];
    82             nxt[i]=min(nxt[i],ma.count(q)?ma[q]:n+1);
    83             ma[q]=i;
    84             while(t%q==0)    t/=q;
    85         }
    86     }
    87     fa[solve(1,n)]=0;
    88     if(fl)    puts("impossible");
    89     else
    90     {
    91         for(i=1;i<=n;i++)
    92         {
    93             printf("%d",fa[i]);
    94             if(i!=n)    putchar(' ');
    95         }
    96         puts("");
    97     }}
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    制作一个螺旋矩阵
    通过C++修改系统时间代码
    绝对值最小
    compile cmdow
    2017-10-04清北模拟赛
    2017-10-03清北模拟赛
    2017-10-01清北模拟赛
    HTML容易遗忘内容(二)
    SSM框架关于后台返回JSON数据中显示很多不需要的字段为NULL
    关于Unix时间戳转北京时间的问题
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9538892.html
Copyright © 2011-2022 走看看