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\n",i,j);
38                 }else{
39                     break;
40                 }
41             }
42         }
43     }
44     printf("%d\n",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\n",A[30]);
32     scanf("%d",&n);
33     if(n == 1){
34         printf("1 0\n");
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\n",prime[i],deg[i]);
56 //    }
57 //    printf("!!!\n");
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\n",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\n",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\n",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\n",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\n",Max.second,depth[lc1]-1);
145         }else{
146             printf("%d %d\n",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\n",in[i],out[i]);
113         if(in[i] + out[i] >= n-2){
114             ans++;
115         }
116     }
117     printf("%d\n",ans);
118 return 0;
119 }
View Code

 

posted @ 2018-11-24 14:00  蒟蒻LQL  阅读(189)  评论(0编辑  收藏  举报