• Codeforces Round #520 (Div. 2)


    A.prank

    题意:给出一个含有n个数的递增的序列,问最多能删除多少个连续的数字,使得这个数列还是只可能有这一种形式。

    分析:那就找出一段最长的差为1的序列就行。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <stack>
     8 #include <cmath>
     9 #include <cstdlib>
    10 #include <set>
    11 #include <map>
    12 
    13 
    14 using namespace std;
    15 typedef long long LL;
    16 typedef unsigned long long ull;
    17 const int INF = 2147000000;
    18 const LL inf = 1e18;
    19 LL gcd(LL a,LL b){
    20     if(!b)return a;
    21     return gcd(b,a%b);
    22 }
    23 const int maxn = 1e3+100;
    24 int n;
    25 int a[maxn];
    26 int main(){
    27     scanf("%d",&n);
    28     for(int i = 1; i <= n; i++)
    29         scanf("%d",&a[i]);
    30     a[n+1]=1001;
    31     int ans=0;
    32     for(int i = 1;i <= n; i++){
    33         if(a[i]==a[i-1]+1){
    34             for(int j=i+1;j<=n+1;j++){
    35                 if(a[j]==a[j-1]+1){
    36                     ans=max(ans,j-i);
    37                   //  printf("%d %d
    ",i,j);
    38                 }else{
    39                     break;
    40                 }
    41             }
    42         }
    43     }
    44     printf("%d
    ",ans);
    45 return 0;
    46 }
    View Code

    B.Math

    题意:给出一个正整数n,可以进行以下两种操作。1将n乘一个整数x。2将n开平方。问最少需要多少次操作能将n变得最小?

    分析:将n唯一分解,n能变得最小得值就是n所有得质因子得乘积。次数就是先将所有质因子得次数都变成一个2得某次方,然后不断开方。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <stack>
     8 #include <cmath>
     9 #include <cstdlib>
    10 #include <set>
    11 #include <map>
    12 
    13 
    14 using namespace std;
    15 typedef long long LL;
    16 typedef unsigned long long ull;
    17 const int INF = 2147000000;
    18 const LL inf = 1e18;
    19 LL gcd(LL a,LL b){
    20     if(!b)return a;
    21     return gcd(b,a%b);
    22 }
    23 int n;
    24 const int maxn=1e6+100;
    25 int prime[maxn],deg[maxn],A[maxn];
    26 int main(){
    27     A[0] = 1;
    28     for(int i = 1; i <= 30; i++){
    29         A[i] = 2 * A[i-1];
    30     }
    31 //    printf("%d
    ",A[30]);
    32     scanf("%d",&n);
    33     if(n == 1){
    34         printf("1 0
    ");
    35         return 0;
    36     }
    37     int N = n, num = 0;
    38     int m = (int)sqrt(n+0.5);
    39     for(int i = 2; i <= m; i++){
    40         if(N%i == 0){
    41             num ++;
    42             prime[num] = i;
    43             while(N%i == 0){
    44                 deg[num]++;
    45                 N /= i;
    46             }
    47         }
    48     }
    49     if(N > 1){
    50         num++;
    51         prime[num] = N;
    52         deg[num] ++;
    53     }
    54 //    for(int i = 1; i <= num; i++){
    55 //        printf("%d %d
    ",prime[i],deg[i]);
    56 //    }
    57 //    printf("!!!
    ");
    58     int ans = 1, ans1 = 1, Max = 0;
    59     for(int i = 1; i <= num; i++){
    60         Max = max(Max , deg[i]);
    61     }
    62     int pos = lower_bound(A,A+31,Max) - A;
    63     if(Max == A[pos]){
    64         ans1 = 0;
    65         if(num!=1){
    66             for(int i = 1; i <= num; i++){
    67                 if(Max != deg[i]){
    68                     ans1 = 1;
    69                     break;
    70                 }
    71             }
    72         }
    73     }
    74     Max = A[pos];
    75     for(int i = 1; i <= num; i++){
    76         ans = ans * prime[i];
    77     }
    78     ans1 += pos;
    79     printf("%d %d
    ",ans,ans1);
    80 return 0;
    81 }
    View Code

    C.Banh-mi

    题意:略

    分析:我对这个题完全没印象了···汗···

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <stack>
     8 #include <cmath>
     9 #include <cstdlib>
    10 #include <set>
    11 #include <map>
    12 
    13 
    14 using namespace std;
    15 typedef long long LL;
    16 typedef unsigned long long ull;
    17 const int mod = 1e9+7;
    18 const int INF = 2147000000;
    19 const LL inf = 1e18;
    20 LL gcd(LL a,LL b){
    21     if(!b)return a;
    22     return gcd(b,a%b);
    23 }
    24 const int maxn = 100000+100;
    25 
    26 LL pow_mod(LL a,LL n,LL m){
    27     if(n==0)return 1;
    28     LL x=pow_mod(a,n/2,m);
    29     LL ans=(LL)x*x%m;
    30     if(n%2==1)ans=ans*a%m;
    31     return ans;
    32 }
    33 int n,q;
    34 char s[maxn];
    35 int sum[maxn];
    36 int main(){
    37     scanf("%d%d",&n,&q);
    38     scanf("%s",s);
    39     for(int i = 0; i < n;i++){
    40         if(s[i]=='1'){
    41             sum[i] = sum[i-1] + 1;
    42         }else{
    43             sum[i] = sum[i-1];
    44         }
    45     }
    46     for(int i = 1; i <= q; i++){
    47         int l , r;
    48         scanf("%d%d",&l,&r);
    49         l--;r--;
    50         int num = sum[r]-sum[l-1];
    51         LL ans = 0;
    52         int last = 1;
    53         LL nn = r - l +1;
    54 
    55         ans = (pow_mod(2,num,mod)-1);
    56         ans =(ans+ ans*(pow_mod(2,nn-num,mod)-1)%mod)%mod;
    57         printf("%I64d
    ",ans);
    58     }
    59     return 0;
    60 }
    View Code

    D.Fun with Integers

    题意:给出一个大于等于2的正整数n,对于每一对正整数a,b,你可以将a变成b当存在一个x满足a*x = b或者b*x =a。每次变完以后的得分是|x|。问最大得分。

    分析:我们发现,对于n以内的每一对满足条件的a,b都可以像样例那么变换。那么只要找出n以内成对的倍数就可以了。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <stack>
     8 #include <cmath>
     9 #include <cstdlib>
    10 #include <set>
    11 #include <map>
    12 
    13 
    14 using namespace std;
    15 typedef long long LL;
    16 typedef unsigned long long ull;
    17 const int INF = 2147000000;
    18 const LL inf = 1e18;
    19 LL gcd(LL a,LL b){
    20     if(!b)return a;
    21     return gcd(b,a%b);
    22 }
    23 int n;
    24 LL ans;
    25 int main(){
    26     scanf("%d",&n);
    27     for(LL i = 2; i <= n/2; i++){
    28         for(LL j = 2; j*i <= n; j++){
    29             ans += 4*j;
    30         }
    31     }
    32     printf("%I64d
    ",ans);
    33 return 0;
    34 }
    View Code

    E.Company

    题意:给出一课有n个点的树,和q个询问,每个询问给出一个区间[li,ri]。你可以删除区间内的一个结点,使得删除以后区间内点的lca深度最大。

    分析:区间的lca怎么求?[l,r]内dfs序最大的点和最小的点的lca就是这个区间的lca。那要删除的点一定就是这两个点其中的一个。按照惯例我们用线段树维护就可以了。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <queue>
      7 #include <stack>
      8 #include <cmath>
      9 #include <cstdlib>
     10 #include <set>
     11 #include <map>
     12 
     13 
     14 using namespace std;
     15 typedef long long LL;
     16 typedef unsigned long long ull;
     17 typedef pair<int,int>pir;
     18 const int INF = 2147000000;
     19 const LL inf = 1e18;
     20 const int maxn = 100000 + 10;
     21 int head[maxn],to[2*maxn],Next[2*maxn];
     22 int depth[maxn],order[maxn],idx[maxn];//order dfs序列,idx是dfs结点的dfs序
     23 int f[maxn][30];
     24 int n,sz,q,maxd,N;
     25 void init(){
     26     sz = 0;
     27     N = 0;
     28     memset(head,-1,sizeof(head));
     29 }
     30 void add_edge(int a,int b){
     31     ++sz;
     32     to[sz] = b;
     33     Next[sz] = head[a];
     34     head[a] = sz;
     35 }
     36 void dfs(int u,int fa,int dep){
     37     depth[u] = dep;
     38     f[u][0] = fa;
     39     N++;
     40     order[N] = u;
     41     idx[u] = N;
     42     for(int i = 1; i <= maxd; i++){
     43         f[u][i] = f[f[u][i-1]][i-1];
     44     }
     45     for(int i = head[u]; i != -1; i = Next[i]){
     46         int v = to[i];
     47         if(v == fa)
     48             continue;
     49         dfs(v, u, dep + 1);
     50     }
     51     return;
     52 }
     53 pir minv[4*maxn],maxv[4*maxn];
     54 void build(int o,int L,int R){
     55     if(L == R){
     56         minv[o].first = idx[L];
     57         minv[o].second = L;
     58         maxv[o] = minv[o];
     59         return ;
     60     }
     61     int M = L +(R - L)/2;
     62     build(2*o,L,M);
     63     build(2*o+1,M+1,R);
     64     minv[o] = min(minv[2*o], minv[2*o+1]);
     65     maxv[o] = max(maxv[2*o], maxv[2*o+1]);
     66 }
     67 
     68 pir query_min(int o,int L,int R,int ql,int qr){
     69         if(ql<=L&&qr>=R){
     70             return minv[o];
     71         }
     72         int M = L + (R - L)/2;
     73         pir res = make_pair(INF,INF);
     74         if(ql <= M)
     75             res = query_min(2*o,L,M,ql,qr);
     76         if(qr > M)
     77             res = min(res, query_min(2*o+1,M+1,R,ql,qr));
     78         return res;
     79 }
     80 
     81 pir query_max(int o,int L,int R,int ql,int qr){
     82         if(ql<=L&&qr>=R){
     83             return maxv[o];
     84         }
     85         int M = L + (R - L)/2;
     86         pir res = make_pair(-INF,-INF);
     87         if(ql <= M)
     88             res = query_max(2*o,L,M,ql,qr);
     89         if(qr > M)
     90             res = max(res, query_max(2*o+1,M+1,R,ql,qr));
     91         return res;
     92 }
     93 
     94 int lca(int u, int v){
     95     if(depth[u] > depth[v])swap(u,v);
     96     for(int i = maxd; i >= 0; i--){
     97         if(depth[f[v][i]] >= depth[u])
     98             v = f[v][i];
     99     }
    100     if(u == v)
    101         return u;
    102     for(int i = maxd; i >= 0; i--){
    103         if(f[u][i] != f[v][i]){
    104             u = f[u][i], v = f[v][i];
    105         }
    106     }
    107     return f[u][0];
    108 }
    109 
    110 int main(){
    111     scanf("%d%d",&n,&q);
    112     maxd = (int)(log(n)/log(2)) + 1;
    113     //printf("%d
    ",maxd);
    114     init();
    115     for(int i = 2; i <= n; i++){
    116         int fa;
    117         scanf("%d",&fa);
    118         add_edge(fa,i);
    119         add_edge(i,fa);
    120     }
    121     dfs(1,-1,1);
    122     build(1,1,n);
    123 
    124     for(int i = 1; i <= q; i++){
    125         int l , r;
    126         scanf("%d%d",&l,&r);
    127         pir Max = query_max(1,1,n,l,r);
    128         pir Min = query_min(1,1,n,l,r);
    129         int lc1,lc2;
    130         //先尝试删最大的
    131         pir max1 = make_pair(-INF,-INF);
    132         if(Max.second > l)
    133             max1 = query_max(1,1,n,l,Max.second-1);
    134         if(Max.second < r)
    135             max1 = max(max1,query_max(1,1,n,Max.second+1,r));
    136         lc1 = lca(max1.second,Min.second);
    137         pir min1 = make_pair(INF,INF);
    138         if(Min.second > l)
    139             min1 = query_min(1,1,n,l,Min.second-1);
    140         if(Min.second < r)
    141             min1 = min(min1,query_min(1,1,n,Min.second+1,r));
    142         lc2 = lca(Max.second,min1.second);
    143         if(depth[lc1] >= depth[lc2]){
    144             printf("%d %d
    ",Max.second,depth[lc1]-1);
    145         }else{
    146             printf("%d %d
    ",Min.second,depth[lc2]-1);
    147         }
    148     }
    149 return 0;
    150 }
    View Code

    F.Upgrading Cities

    这个题参考的一位巨巨的博客:https://blog.csdn.net/corsica6/article/details/84098779

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <queue>
      6 
      7 
      8 using namespace std;
      9 const int maxn = 300000+100;
     10 int n,m,sz,l,r;
     11 int head[maxn],Next[maxn],to[maxn],in[maxn],out[maxn],deg[maxn],q[maxn];
     12 void init(){
     13     sz = 0;
     14     memset(deg,0,sizeof(deg));
     15     memset(head,-1,sizeof(head));
     16 }
     17 void add_edge(int a,int b){
     18     ++sz;
     19     to[sz] = b;
     20     Next[sz] = head[a];
     21     head[a] = sz;
     22 }
     23 struct Edge{
     24     int from,to;
     25 }edges[maxn];
     26 int main(){
     27     init();
     28     scanf("%d%d",&n,&m);
     29     for(int i = 1; i <= m; i++){
     30         int a , b;
     31         scanf("%d%d",&a,&b);
     32         edges[i].from = a;
     33         edges[i].to = b;
     34         add_edge(a,b);
     35         deg[b]++;
     36     }
     37     l = r = 0;
     38     for(int i = 1; i <= n; i++){
     39         if(!deg[i]){
     40             q[r++] = i;
     41         }
     42     }
     43 
     44     while(l<r){
     45         int u = q[l++];
     46         if(l==r){
     47             out[u] = n - r;
     48         }else if(l+1 == r){
     49             int v = q[l];
     50             int flag = 1;
     51             for(int i = head[v]; i!=-1; i = Next[i]){
     52                 int vv = to[i];
     53                 if(deg[vv] == 1){
     54                     flag = 0;
     55                     break;
     56                 }
     57             }
     58             if(!flag)
     59                 out[u] = -n;
     60             else
     61                 out[u] = n - r;
     62         }else
     63             out[u] = -n;
     64 
     65         for(int i = head[u]; i!=-1; i = Next[i]){
     66             int v = to[i];
     67             deg[v]--;
     68             if(!deg[v])
     69                 q[r++] = v;
     70         }
     71     }
     72     init();
     73     for(int i = 1; i <= m; i++){
     74         add_edge(edges[i].to,edges[i].from);
     75         deg[edges[i].from]++;
     76     }
     77     l=r=0;
     78     for(int i = 1; i <= n; i++){
     79         if(!deg[i]){
     80             q[r++] = i;
     81         }
     82     }
     83     while(l<r){
     84         int u = q[l++];
     85         if(l==r){
     86             in[u] = n - r;
     87         }else if(l+1 == r){
     88             int v = q[l];
     89             int flag = 1;
     90             for(int i = head[v]; i != -1; i = Next[i]){
     91                 int vv = to[i];
     92                 if(deg[vv] == 1){
     93                     flag = 0;
     94                     break;
     95                 }
     96             }
     97             if(!flag)
     98                 in[u] = -n;
     99             else
    100                 in[u] = n - r;
    101         }else
    102             in[u] = -n;
    103         for(int i = head[u]; i != -1; i = Next[i]){
    104             int vv = to[i];
    105             deg[vv] --;
    106             if(!deg[vv])
    107                 q[r++] = vv;
    108         }
    109     }
    110     int ans = 0;
    111     for(int i = 1; i <= n; i++){
    112        // printf("%d %d
    ",in[i],out[i]);
    113         if(in[i] + out[i] >= n-2){
    114             ans++;
    115         }
    116     }
    117     printf("%d
    ",ans);
    118 return 0;
    119 }
    View Code
  • 相关阅读:
    电容的串联和并联的性质
    start.sh
    shell 得到当前目录路径
    Java程序远程无法执行nohup命令
    mysql windows 安装5.7
    电阻并联的性质
    电阻串联的性质
    webjars
    邮箱设置
    万用表使用注意事项
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/10011917.html
Copyright © 2020-2023  润新知