1285B Just Eat It!
最大子段和(dp O(n))
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
long long dp[maxn];
int arr[maxn];
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int T; cin >> T;
while(T--){
memset(dp,0,sizeof(dp));
memset(arr,0,sizeof(arr));
int n; cin >> n;
long long sum = 0;
for(int i = 1; i <= n; ++i){
int x; cin >> arr[i];
sum += arr[i];
}
long long maxx = -1e9; int l = 0,r = -1;
int ll = 0,rr = 0;
for(int i = 1; i <= n; ++i){
if(dp[i-1] > 0) dp[i] = dp[i-1] + arr[i], r = i;
else dp[i] = arr[i],l = r = i;
if(maxx < dp[i]){
maxx = max(dp[i],maxx);
ll = l,rr = r;
}
}
if(sum < maxx){
cout << "NO"<<endl;
}else if(sum==maxx){
if(ll==1 && rr==n)
cout << "YES" << endl;
else cout << "NO" << endl;
}else cout << "YES" << endl;
}
return 0;
}
C.
#include <bits/stdc++.h>
using namespace std;
int main()
{
typedef long long ll;
ll x; cin >> x; ll ans = 0;
for(ll i = 1; i*i <= x; ++i){
if(x%i==0 && __gcd(i,x/i)==1){
ans = i;
}
}
cout << ans << ' ' << x/ans << endl;
return 0;
}
C - Valera and Elections
树上的问题,给出一棵树,有些树边是坏的,让你给出一个元素最小的集合,对于集合内每个数我可以修复1~i之间的路,然后使得整个树被修好。
发现只要选择那些结点满足:该结点的子树没有坏的边且该结点与父亲连的边是坏的,我们就选择
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
struct Edge{
int u,v,nxt,w;
}edge[maxn]; int tot,head[maxn];
inline void init(){
memset(head,-1,sizeof(head));
}
inline void addedge(int u,int v,int w){
edge[++tot] = Edge{u,v,head[u],w};
head[u] = tot;
}
set<int> ans;
inline int dfs(int u,int fa,int tag){
int isok = 0;
for(int i = head[u]; ~i; i = edge[i].nxt){
Edge &e = edge[i];
if(e.v!=fa){
if(e.w==2) isok = 1;
if(e.w==1) isok = max(isok,dfs(e.v,u,0));
else isok = max(isok,dfs(e.v,u,1));
}
}
if(!isok && tag) ans.insert(u);
return isok;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin >> n; init();
for(int i = 1; i < n; ++i){
int u,v,w; cin >> u >> v >> w;
addedge(u,v,w);
addedge(v,u,w);
}
dfs(1,-1,0);
cout << ans.size() << endl;
for(auto i : ans){
cout << i << ' ';
}cout << endl;
return 0;
}
427C - Checkposts
tarjan缩点裸题
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+5;
const int mod = 1e9+7;
int dfn[maxn],low[maxn],sta[maxn],stalen,cnt;
long long arr[maxn];
bool vis[maxn];
int num[maxn];
struct Edge{
int u,v,nxt;
}edge[maxn]; int head[maxn],edgetot;
inline void addedge(int u,int v){
edge[++edgetot] = {u,v,head[u]};
head[u] = edgetot;
}
typedef long long ll;
ll ans = 1,totalcost = 0;
inline void tarjan(int u){
dfn[u] = low[u] = ++cnt;
sta[stalen++] = u; vis[u] = true;
for(int i = head[u]; ~i; i = edge[i].nxt){
Edge &e = edge[i];
if(!dfn[e.v]){
tarjan(e.v);
low[u] = min(low[u],low[e.v]);
}else if(vis[e.v])low[u] = min(low[u],dfn[e.v]);
}
if(dfn[u]==low[u]){
int cur,minn = 1e9,tot = 0;
do{
cur = sta[--stalen];
vis[cur] = false;
if(minn > arr[cur]){
minn = arr[cur];
tot = 1;
}else if(minn==arr[cur]) ++tot;
}while(u!=cur);
ans = (ans*tot)%mod; totalcost += minn;
//cout << endl;
}
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin >> n;
for(int i = 1; i <= n; ++i) cin >> arr[i];
int m; cin >> m;
memset(head,-1,sizeof(head));
for(int i = 0; i < m; ++i){
int u,v; cin >> u >> v; addedge(u,v);
}
for(int i = 1; i <= n; ++i){
if(!dfn[i]) tarjan(i);
}
cout << totalcost << ' ' << ans << endl;
return 0;
}
D. Unbearable Controversy of Being
暴力就行
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
struct Edge{
int u,v,nxt;
}edge[maxn]; int head[maxn],tot;
bool vis[maxn];
map<int,int> mp[maxn];
inline void addedge(int u, int v){
edge[++tot] = Edge{u,v,head[u]};
head[u] = tot;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
memset(head,-1,sizeof(head));
int n,m; cin >> n >> m;
for(int i = 0; i < m; ++i){
int u,v; cin >> u >> v;
addedge(u,v);
}
for(int i = 1; i <= n; ++i){
for(int j = head[i]; ~j; j = edge[j].nxt){
Edge &e = edge[j];
for(int k = head[e.v]; ~k; k = edge[k].nxt){
Edge &E = edge[k];
mp[E.v][i]++;
}
}
}
long long ans = 0;
for(int i = 1; i <= n; ++i){
for(auto j : mp[i]){
if(j.second>=2 && j.first !=i) ans += j.second*(j.second-1)/2;
}
}
cout << ans << endl;
return 0;
}
522A
dfs记录状态dp搞一下即可挺简单的一个题
#include <bits/stdc++.h>
using namespace std;
map<string,int> mp;
const int maxn = 1e5+5;
struct Edge{
int u,v,nxt;
}edge[maxn];
int head[maxn],tot;
int cnt;
inline void addedge(int u,int v){
edge[++tot] = Edge{u,v,head[u]};
head[u] = tot;
}
int dp[maxn];
inline void dfs(int u,int fa,int depth){
if(dp[u]!=1) return;
for(int i = head[u]; ~i; i = edge[i].nxt){
Edge &e = edge[i];
if(e.v!=u){
dfs(e.v,u,depth+1);
dp[u] = max(dp[u],dp[e.v]+1);
}
}
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n; cin >> n; memset(head,-1,sizeof(head));
for(int i = 1; i <= 1e5; ++i) dp[i] = 1;
for(int i = 0; i < n; ++i){
string s1,s2,s3; cin >> s1 >> s2 >> s3;
for(int j = 0; j < s1.size(); ++j) s1[j] = tolower(s1[j]);
for(int j = 0; j < s3.size(); ++j) s3[j] = tolower(s3[j]);
if(!mp.count(s1)) mp[s1] = ++cnt; if(!mp.count(s3)) mp[s3] = ++cnt;
// cout << mp[s1] << ' ' <<mp[s3]<< endl;
addedge(mp[s1],mp[s3]);
}
for(int i = 1; i <= cnt; ++i){
dfs(i,-1,0);
// cout << i << ' ' << dp[i] << endl;
}
cout << *max_element(dp+1,dp+cnt+1) << endl;
return 0;
}