Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)

B2 - TV Subscriptions (Hard Version)

遍历,维护一个set和set<pair<int,int>>即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e6+7;
 5 const ll mod = 1e9 + 9;
 6 #define afdafafafdafaf y1;
 7 int ar[maxn], n, m, k;
 8  
 9 int d[maxn];
10 int main()
11 {
12     int t;
13     scanf("%d", &t);
14     while(t--){
15         scanf("%d%d%d", &n, &m, &k);
16         for(int i=1;i<=n;i++)scanf("%d", ar+i);
17         for(int i=1;i<=n;i++)d[ar[i]] = 0;
18         set<int> s;
19         set<pair<int,int> > sp;
20         for(int i=1;i<=k;i++){
21             d[ar[i]]++;
22         }
23         for(int i=1;i<=k;i++){
24             s.insert(ar[i]);
25             sp.insert(make_pair(ar[i], d[ar[i]]));
26         }
27         int ans = s.size();
28         for(int i = k + 1; i <= n; i++){
29             int x = ar[i - k];
30             sp.erase(make_pair(x, d[x]));
31             d[x]--;
32             if(d[x] > 0){
33                 sp.insert(make_pair(x, d[x]));
34             }
35             else{
36                 s.erase(x);
37             }
38             x = ar[i];
39             sp.erase(make_pair(x, d[x]));
40             d[x]++;
41             sp.insert(make_pair(x, d[x]));
42             if(d[x] == 1)s.insert(x);
43             ans = min(ans, int(s.size()));
44         }
45         printf("%d\n", ans);
46     }
47     
48     return 0;
49 }
View Code

C - p-binary

暴力尝试。。。。

try a try, ac is ok

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e6+7;
 5 const ll mod = 1e9 + 9;
 6 #define afdafafafdafaf y1;
 7 int ar[maxn], n, m, k;
 8  
 9 int d[maxn];
10 int main()
11 {
12     ll n, p;
13     int flag = 0;
14     scanf("%lld%lld", &n, &p);
15     for(ll i=1;i<=int(3e5);i++){
16         ll x = n - p * i, pre = x;
17         int ins = 0;
18         while(x > 0){
19             if(x & 1)ins++;
20             x /= 2;
21         }
22         if(i <= pre && i >= ins){
23             printf("%d\n", i);
24             flag = 1;
25             break;
26         }
27     }
28     if(flag != 1){
29         printf("-1\n");
30     }
31     return 0;
32 }
View Code

D - Power Products

一个数如果可以形成x^k的形式,那他的每一个质因子的次幂一定是k的倍数,对每一个数的每个质因子幂%k,对k取补值(即补值*原值就是x^k的形式) 

找出能和每个数相乘能符合条件的最小补值,求个对数集即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e6+7;
 5 const ll mod = 1e9 + 9;
 6 #define afdafafafdafaf y1;
 7 int ar[maxn], n, m, k;
 8  
 9 int d[maxn], rev[maxn];
10 int main()
11 {
12     scanf("%d%d", &n, &k);
13     for(int i=1;i<=n;i++)scanf("%d", ar+i);
14     for(int in=1;in<=n;in++){
15         ll x = ar[in];
16         ll re = 1;
17         for(int i=2; i<=sqrt(x);i++){
18             int ins = 0;
19             ll base = 1, ss = 1;
20             while(x % i == 0){
21                 ss *= i;
22                 ins++;
23                 x /= i;
24             }
25             if(ins > 0){
26                 for(int j=0;j<k;j++){
27                     base *= i;
28                     if(base > ll(1e10)){
29                         base = 0;
30                         ar[in] = 0;
31                         re = 0;
32                         break;
33                     }
34                 }
35                 if(base == 0)break;
36                 while(ss % base == 0){
37                     ss /= base;
38                     ar[in] /= base;
39                 }
40                 assert(base % ss == 0);
41                 if(ss != 1)re *= (base / ss);
42                 if(re > int(1e5)){
43                     re = 0;
44                     ar[in] = 0;
45                     break;
46                 }
47             }
48         }
49         if(x > 1 && re != 0){
50             for(int j = 0; j < k - 1; j++){
51                 re *= x;
52                 if(re > int(1e5)){
53                     re = 0;
54                     ar[in] = 0;
55                     break;
56                 }
57             }
58         }
59         if(ar[in] > 0)d[ar[in]]++;
60         rev[in] = re;
61         //cout<< ar[in] << ' ' << rev[in] << '\n';
62     }
63     ll sum = 0;
64     for(int i=1;i<=n;i++){
65         if(rev[i] > int(1e5) || rev[i] == 0)continue;
66         sum += d[rev[i]];
67         if(ar[i] == rev[i] && ar[i] > 0)sum--;
68     }
69     printf("%lld\n", sum / 2);
70  
71  
72     return 0;
73 }
View Code

E - Rock Is Push

对每个点求向右,向下能走到的最远的点

每次dp的时候,只需要计算左边的点向下走的次数,上面的点向右的次数即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 2e3+7;
 5 const ll mod = 1e9 + 7;
 6 #define afdafafafdafaf y1;
 7 int ar[maxn], n, m, k;
 8  
 9 char g[maxn][maxn];
10 ll s[2][maxn][maxn<<2];
11 void add(int ins, int x, int y, ll val){
12     while(y <= max(n, m)){
13         s[ins][x][y] += val + mod;
14         s[ins][x][y] %= mod;
15         y += y & (-y);
16     }
17 }
18 ll que(int ins, int x, int y){
19     ll ans = 0;
20     while(y > 0){
21         ans += s[ins][x][y] + mod;
22         ans %= mod;
23         y -= y & (-y);
24     }
25     return ans;
26 }
27 void add_all(int ins, int x, int l, int r, ll val){
28     add(ins, x, l, val);
29     add(ins, x, r+1, -val);
30 }
31 int r[maxn][maxn], c[maxn][maxn], f_r[maxn], f_c[maxn];
32 ll ans[maxn][maxn];
33 int main()
34 {
35     scanf("%d%d", &n, &m);
36     for(int i=1;i<=n;i++){
37         scanf("%s", g[i] + 1);
38     }
39     for(int i=1;i<=n;i++){
40         //cout << g[i] + 1 << '\n';
41     }
42     for(int i = n; i >= 1; i--){
43         for(int j = m; j >= 1; j--){
44             r[i][j] = r[i][j+1] + (g[i][j] == '.'); 
45             c[i][j] = c[i+1][j] + (g[i][j] == '.'); 
46         }
47     }
48     /*
49     for(int i=1;i<=n;i++){
50         for(int j=1;j<=m;j++)cout<< r[i][j] << ' '; cout << '\n';
51     }
52     for(int i=1;i<=n;i++){
53         for(int j=1;j<=m;j++)cout<< c[i][j] << ' '; cout << '\n';
54     }
55     cout<<"\n\n";
56     */
57     for(int i=1;i<=n;i++){
58         for(int j=1;j<=m;j++){
59             ll rs = 0, cs = 0;
60             if(i == 1 && j == 1){
61                 rs = cs = 1;
62             }
63             if(j != 1){
64                 rs = que(0, i, j);
65             }
66             int len1;
67             len1 = c[i+1][j];
68             add_all(1, j, i+1, i+len1, rs);
69             if(i != 1){
70                 cs = que(1, j, i);
71             }
72             int len2 = r[i][j+1];
73             add_all(0, i, j+1, j+len2, cs);
74             if(i == 1 && j == 1)ans[i][j] = 1;
75             else ans[i][j] = rs + cs;
76             //cout<< i <<' ' << j << ' ' << rs << ' ' << cs << ' ' << len1 << ' ' << len2 << '\n';
77         }
78     }
79     printf("%lld\n", ans[n][m] % mod);
80     return 0;
81 }
View Code

拖神的dp复杂度更牛逼

附个链接吧

https://codeforc.es/contest/1246/submission/63454015

猜你喜欢

转载自www.cnblogs.com/wa007/p/11746204.html