Codeforces Edu Round 54 A-E

A. Minimizing the String

Obviously, greedy Comparison from front to back of a different character, so you can consider every front to back, if it is deleted, this one he becomes \ (str [i + 1] \) , so long as the \ (str [i]> str [i + 1] \) , after deletion must be optimal.

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 200010;
int n;
char str[N];
int main(){
    scanf("%d%s", &n, str + 1);
    for(int i = 1; i < n; i++){
        if(str[i] > str[i + 1]){
            for(int j = 1; j <= n; j++)
                if(j != i) printf("%c", str[j]);
            return 0;
        }
    }
    for(int i = 1; i < n; i++)
        printf("%c", str[i]);
    return 0;
}

B. Divisor Subtraction

Pure violence can time out, taking into account all the even the smallest prime factors are \ (2 \) , it can be classified discussions for a number \ (the X-\) :

  1. If \ (X \% 2 = 0 \) , each time the \ (D = 2 \) , number of operations \ (x / 2 \)
  2. If \ (X \) is a prime number, the minimum quality factor X = $ \ (, \) X - $ X = 0, number of operations \ (1 \)
  3. If \ (X \) is an odd number of bonding, the quality factor thereof must also be an odd number, so \ ((X - D) \% 2 = 0 \) , may be returned first solution.

C. Meme Problem

In accordance with the meaning of the questions, the equation into a quadratic equation, and then solving pursuant to root formula.

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int d;
int main(){
    int T; scanf("%d", &T);
    while(T--){
        scanf("%d", &d);
        double a, b, delta;
        delta = d * d - 4 * d;
        if(delta < 0) puts("N");
        else delta = sqrt(delta), printf("Y %.9f %.9f\n", (delta + d) / 2, (-delta + d) / 2);
    }
    return 0;
}

D. Edge Deletion

Can first \ (the Dijkstra \) trees with a shortest, and greedy, from node \ (1 \) Start \ (Bfs \) , selecting \ (K \) edges can.

(PS: did not open \ (Long \) \ (Long \) is caught \ (Wa \) a \ (N \) times)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;

const int N = 300010, M = 300010;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, numE = 1, head[N], fa[N], faEdge[N];
bool vis[N];
vector<int> G[N], ans;
LL dis[N];
priority_queue<PLI, vector<PLI>, greater<PLI> > q;
queue<int> Q;
struct Edge{
    int next, to;
    LL dis;
}e[M << 1];
void addEdge(int from, int to, int dis){
    e[++numE].next = head[from];
    e[numE].to = to;
    e[numE].dis = dis;
    head[from] = numE;
}
void Dijkstra(){
    memset(dis, 0x3f, sizeof dis);
    
    q.push(make_pair(0, 1)); dis[1] = 0;
    while(!q.empty()){
        PLI u = q.top(); q.pop();
        if(vis[u.second]) continue;
        vis[u.second] = true;
        for(int i = head[u.second]; i; i = e[i].next){
            int v = e[i].to;
            if(dis[u.second] + e[i].dis < dis[v]){
                dis[v] = dis[u.second] + e[i].dis;
                fa[v] = u.second, faEdge[v] = i >> 1;
                q.push(make_pair(dis[v], v));
            }
        }
    }
}
void Bfs(){
    
    Q.push(1);
    while((!Q.empty()) && k > 0){
        int u = Q.front(); Q.pop();
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i]; k--;
            ans.push_back(faEdge[v]);
            Q.push(v);
            if(!k) return; 
        }
    }
}
int main(){
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= m; i++){
        int u, v, w; scanf("%d%d%d", &u, &v, &w);
        addEdge(u, v, w); addEdge(v, u, w);
    }
    Dijkstra();
    for(int i = 1; i <= n; i++)  
        if(fa[i]) G[fa[i]].push_back(i);
    Bfs();
    printf("%d\n", (int)ans.size());
    for(int i = 0; i < ans.size(); i++)
        printf("%d ", ans[i]);
    return 0;
}

E. Vasya and a Tree

Consider something and maintenance, now it changes similar to "scan the tree line" with Fenwick tree because the tree traversal before the child will dfs to its ancestor, so when the ancestors of the sections to be processed, plus enter to exit to cut ...

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 3 * 1e5 + 5;
typedef long long ll;
struct Edge{
    int next,to;
}e[N * 2];
int n,m,head[N],numE=0;
ll c[N],ans[N];
vector<pair<int,int> > T[N];
void addEdge(int from,int to){
    e[++numE].next = head[from];
    e[numE].to = to;
    head[from] = numE;
}
ll ask(int x){
    ll ans = 0; 
    for(;x;x-=x&-x)ans += c[x];
    return ans;
}
void add(int x,ll k){
    for(;x<=n;x+=x&-x)c[x] += k;
}
void dfs(int u,int last,int dep){
    for(int i=0;i<T[u].size();i++){
        int d = T[u][i].first;
        ll x = T[u][i].second;
        add(dep,x);
        add(dep + d + 1,-x);
    }
    ans[u] = ask(dep);
    for(int i = head[u];i;i=e[i].next){
        int v = e[i].to;
        if(v == last)continue;
        dfs(v,u,dep + 1);
    }
    for(int i=0;i<T[u].size();i++){
        int d = T[u][i].first;
        ll x = T[u][i].second;
        add(dep,-x);
        add(dep + d + 1,+x);
    }
}
int main() {
    scanf("%d",&n);
    for(int i=2;i<=n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        addEdge(x,y);
        addEdge(y,x);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        int v,d,x;
        scanf("%d%d%d",&v,&d,&x);
        T[v].push_back(make_pair(d,x));
    } 
    dfs(1,0,1);
    for(int i=1;i<=n;i++){
        printf("%lld ",ans[i]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/dmoransky/p/11278278.html