CodeForces Round 525

A:Ehab and another construction problem

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;

int main(){
    int x;
    scanf("%d", &x);
    for(int i = 1; i <= x; ++i)
    for(int j = 1; j <= x; ++j){
        if(i%j == 0 && i*j > x && i/j < x){
            cout << i << ' ' << j << endl;
            return 0;
        }
    }
    cout << -1 << endl;
    return 0;
}
View Code

 

B:Ehab and subtraction

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
int a[N];
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    sort(a+1, a+1+n);
    int val = 0, b = 1;
    for(int i = 1; i <= m; ++i){
        while(b <= n && val >= a[b]) 
            ++b;
        if(b > n)
            puts("0");
        else {
            printf("%d\n", a[b]-val);
            val = a[b];
        }
    }
    return 0;
}
View Code

 

C:Ehab and a 2-operation task

题意:要求构造一个严格递增序列。

题解:一共最多有n+1次操作,所以我们从后往前每次构造第i个数, 把他构造成对%n之后的余数为(i-1)。 最后再对整个数列%n就好了。

代码:

Copy
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
int n;
int a[N];
struct Node{
    int op, l, r;
};
vector<Node> ans;
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    int val = 0;
    for(int i = n; i >= 1; --i){
        a[i] += val;
        int t = a[i]%n;
        if(t == i-1) continue;
        t = (n+(i-1) - t);
        val += t;
        ans.pb({1, i, t});
    }
    ans.pb({2, n, n});
    printf("%d\n", ans.size());
    for(auto it : ans){
        printf("%d %d %d\n", it.op, it.l, it.r);
    }
    return 0;
}
View Code

 

DEhab and another another xor problem

交互题。

题解:

我们可以通过输出 0 0 来判断 a 和 b的大小。

然后我们考虑ab的二进制。

从高位往地位枚举  

     将第i位^1之后, 如果 a和b的亦或后的大小没发生改变, 则说明第i位是一样01码的。

        将第i位^1之后, 如果 a和b的亦或后的大小发生了变化, 那么就说明第i位的01码是不一样的,并且原来大的那个数第i位是1,记录下这一位的变化, 然后前面这一位考虑进去之后,重新询问接来下的剩下位数的ab大小。

经过上面的操作,我们就确定了不一样的位置的信息,然后在去找同意位置上的信息就好了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
int t, val, f = 0;
int ans1, ans2;
int vis[N];
int xx = 10, yy = 5;
int gg(int x, int y){
    x ^= xx; y ^= yy;
    if(x > y) return 1;
    if(x ==y) return 0;
    return -1;
}
int main(){
    printf("? 0 0\n");
    fflush(stdout);
    scanf("%d", &t);
    f = t;
    for(int i = 29; i >= 0 && f != 0; --i){
        int o1 = 1 << i;
        int o2 = o1 ^ val;
        printf("? %d %d\n", o1, o2);
        fflush(stdout);
        scanf("%d", &t);
        if(f == 1){
            if(t == -1){
                val ^= o1;
                ans1 ^= o1;
                vis[i] = 1;
                printf("? %d %d\n", 0, val);
                fflush(stdout);
                scanf("%d", &f);
            }
        }
        else if(f == -1){
            if(t == 1){
                val ^= o1;
                ans2 ^= o1;
                vis[i] = 1;
                printf("? %d %d\n", 0, val);
                fflush(stdout);
                scanf("%d", &f);
            }
        }
    }
    for(int i = 29; i >= 0; --i){
        if(vis[i]) continue;
        int o1 = 1 << i;
        int o2 = val;
        printf("? %d %d\n", o1, o2);
        fflush(stdout);
        scanf("%d", &t);
        if(t == -1){
            ans1 ^= o1;
            ans2 ^= o1;
        }
    }
    printf("! %d %d\n", ans1, ans2);
    fflush(stdout);
    return 0;
}
View Code

 

E:Ehab and a component choosing problem

题意:在一颗树上,每个点都有权值, 你可以选择k个联通块, 使得 所有选得的点的和/k的值最大, 在保证值最大的前提下, k最大。

题解:所有选择的点/k 。 我们考虑这个东西, 肯定就是 这k个块的值都是一样的。并且我们需要保证这值是图中最大的值。

那么我们可以通过dfs找到这个值最大是多少。

然后在通过dfs去check最多有多少个这种块。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 3e5 + 100;
int a[N];
vector<int> vc[N];
LL ans = _INF;
LL dfs1(int o, int u){
    LL val = a[u];
    for(int v : vc[u]){
        if(v == o) continue;
        val += max(0ll, dfs1(u,v));
    }
    ans = max(ans, val);
    return val;
}
int k = 0;
LL dfs2(int o, int u){
    LL val = a[u];
    for(int v : vc[u]){
        if(v == o) continue;
        val += max(0ll, dfs2(u,v));
    }
    if(val == ans) ++k, val = 0;
    return val;
}
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    for(int i = 1,u,v; i < n; ++i){
        scanf("%d%d", &u, &v);
        vc[u].pb(v); vc[v].pb(u);
    }
    dfs1(0,1);
    dfs2(0,1);
    cout << 1ll * ans * k << ' ' << k << endl;
    return 0;
}
View Code

 

F:Ehab and a weird weight formula

题意:给定一棵树,每个节点有权值,并且只有所有权值中,最小值的点只有一个。 并且除了最小值的那个点, 其他的点连向的点中,一定有一个点的 v[u] < v[i]。现在要求你重构这棵树,然后使得

1. 每个点的度数 * v[i]  + 2. 对与新图的每条边的{u,v}  ->  log(dis(u,v)) * min(a[u], a[v]) 所有和最小。

题解:

我们需要证明一个东西,即从权值最小的那个点出发之后, 对于某条链来说,深度越大的点的权值一定大于深度小的点。

假如存在一条链: A -> B -> C -> D 

A是其中最小的点。  

我们假设 v[B] > v[A],  v[C] < v[B] 

因为需要满足题目给定的那个条件, 所以 v[D] < v[C]。

那么对于D来说也需要存在一个点的值是小于D的, 但是不存在这种点, 所以这个假设是矛盾的。

我们可以简单证得 从最小点出发, 他的值是递增的。

然后我们倍增跑一下每个点的每层祖先是什么就好了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 5e5 + 100;
int v[N];
LL ans = 0;
int anc[N][20];
vector<int> vc[N];
void dfs(int o, int u){
    anc[u][0] = o;
    for(int i = 1; i < 20; ++i) anc[u][i] = anc[anc[u][i-1]][i-1];
    if(o){
        LL tmp = INF;
        for(int i = 0; i < 20; ++i){
            tmp = min(tmp, 1ll*v[anc[u][i]]*(i+1));
        }
        tmp += v[u];
        ans += tmp;
    }
    for(int v : vc[u]){
        if(v == o) continue;
        dfs(u, v);
    }
}
int main(){
    int n;
    int rt = 1;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i){
        scanf("%d", &v[i]);
        if(v[i] <= v[rt]) rt = i;
    }
    for(int i = 1,u,v; i < n; ++i){
        scanf("%d%d", &u, &v);
        vc[u].pb(v);
        vc[v].pb(u);
    }
    v[0] = v[rt];
//    cout << "bug" << endl;
    dfs(0, rt);

    printf("%lld\n", ans);
    return 0;
}
View Code

 

posted @ 2018-12-09 13:58  Schenker  阅读(144)  评论(0编辑  收藏  举报