雜題

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;
}
發佈了63 篇原創文章 · 獲贊 14 · 訪問量 6385
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章