终于开始补提了
重点 : C, E的倒着算, F的染色,G的相邻的转换;
B - Hard Calculation
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 4e5+10, mod = 1e9+7;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}int main()
{LL a, b;scanf("%lld%lld", &a, &b);while(a||b){if(a%10 + b%10 >= 10)return puts("Hard"), 0;a /= 10; b /= 10;}puts("Easy");return 0;
}
C - Cheese
思路 : 倒着算,直接减,和上海热身赛B都好神奇。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 3e5+10, mod = 998244353;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}int n, w;
PII a[N];
int main()
{scanf("%d%d", &n, &w);for(int i = 1;i <= n;i ++){int x, y;scanf("%d%d", &x, &y);a[i] = {-x, y};}sort(a+1, a+n+1);LL ans = 0;for(int i = 1;i <= n;i ++){int mi = min(a[i].second, w);ans += (LL)mi*a[i].first;w -= mi;}cout<<-ans<<endl;return 0;
}
D - Longest X
思路 : 双指针或二分,练一下双指针,哎。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 2e5+10, mod = 1e9+7;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}char c[N];
int main()
{int k;scanf("%s%d", c, &k);int num = 0, l = 0, r = 0, ans = 0;while(c[r]){if(c[r] == 'X') r++;else if(num == k) num -= c[l++]=='.';else if(num < k) num ++, r++;ans = max(ans, r-l);}cout<<ans<<endl;return 0;
}
E - Graph Destruction
思路 :从后往前算,倒着并查集合并。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 2e5+10, mod = 1e9+7;vector<int>G[N];
int fa[N], num = 0;
int find(int u){return fa[u] == u ? fa[u]:fa[u] = find(fa[u]);}void dfs(int u)
{if(!u)return ;int t = num;num++;int y = find(u);for(auto x : G[u]){int a = find(x);if(a != y) num--, fa[a] = y;}dfs(u-1);cout<<t<<endl;return ;
}
int main()
{int n, m;scanf("%d%d", &n, &m);for(int i = 1;i <= n;i ++) fa[i] = i;while(m --){int a, b;scanf("%d%d", &a, &b);if(a > b) swap(a, b);G[a].push_back(b);}dfs(n);return 0;
}
F - Make Bipartite
思路 : dp,给每个点染色之后就可以清晰的得到要删哪条边了,但是这是个封闭图形,题解就确定了起点的颜色,然后算到第n个点,这时候先不考虑n到1的边 。 然后再枚举n和1的四种颜色组合,枚举的时候要注意n到0的边已经删过了,因为这个wa了两次。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 3e5+10, mod = 998244353;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}LL dp[N][2][2];
int a[N], b[N];int main()
{int n;scanf("%d", &n);for(int i = 1;i <= n;i ++)scanf("%d", a+i);for(int i = 1;i <= n;i ++)scanf("%d", b+i);memset(dp, 0x7f, sizeof dp);dp[1][0][0] = a[1];dp[1][1][1] = 0;for(int i = 2;i <= n;i ++){dp[i][1][0] = min(dp[i-1][1][0]+b[i-1], dp[i-1][0][0]);dp[i][1][1] = min(dp[i-1][1][1]+b[i-1], dp[i-1][0][1]);dp[i][0][0] = min(dp[i-1][1][0], dp[i-1][0][0]+b[i-1])+a[i];dp[i][0][1] = min(dp[i-1][1][1], dp[i-1][0][1]+b[i-1])+a[i];}cout<<min(min(dp[n][0][0], dp[n][1][1]) + b[n], min(dp[n][1][0], dp[n][0][1]));return 0;
}
G - Longest Y
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <map>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 3e5+10, mod = 998244353;
void mull(int &a, LL b){a = a*b%mod;return ;}
void add(int &a, LL b){a = (a+b)%mod;return ;}int b[N], idx; // 看哪个题解的,放到一起连续就是坐标减去指数相等。
string c;
LL k, a[N]; // a数组是前缀和,方便计算一段区间放到的最小步数; bool ch(int len)
{for(int r = len;r <= idx;r ++){int l = r-len+1, lle = mid-l+1;LL sum = (LL)b[mid]*lle - (a[mid]-a[l-1]) + a[r]-a[mid] - (LL)b[mid]*(len-lle);if(sum<=k)return 1; }return 0;
}int main()
{cin>>c>>k;for(int i = 0;i < c.size();i ++)if(c[i] == 'Y')b[++idx] = i-idx;sort(b+1, b+idx+1);for(int i = 1;i <= idx;i ++)a[i] = a[i-1]+b[i];int l = 0, r = idx+1;while(l < r) // 二分都是找到连续区间的右边的左端点; {if(ch(mid))l = mid+1;else r = mid; }cout<<--l<<endl;return 0;
}