终于开始补提了
重点 : 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;
}