codeforces Round#747 div2

A

A

题意:

找到一对l到r使得l累加到r的和为n

题解

#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
void solve() {
    int n;
    cin>>n;
    cout<<-n+1<<' '<<n<<endl;
}
signed main() {
    ios::sync_with_stdio(false);cin.tie(0);
    int _; cin >> _; while (_--) 
    solve();
    return 0;
}

B

B

题意:

一个数字要求只能是n的不同次方组成,求这些数字中第k大个

思路:

只能由不同的n的次方组成,也就意味着是一个二进制数,当n等于2时,k就是第k大个数,二进制可以表示任何数,所以其他的数字按照二进制模拟即可

题解:

#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
const int mod=1e9+7;
void solve() {
    int n,k;
    cin>>n>>k;
    if(n==2) {
        cout<<k<<endl;
        return;
    }
    int res=0;
    int a=1;
    while(k){
        if(k&1) res=(res+a)%mod;
        a=(a*n)%mod;
        k>>=1;
   }
   cout<<res<<endl;
}
signed main() {
    ios::sync_with_stdio(false);cin.tie(0);
    int _; cin >> _; while (_--) 
    solve();
    return 0;
}

C

C

题意:

给定一个字符串和一个字符c,选择一个x只有当下标i(从1开始)不能被x整除时,s[i]可以变成c,求最小操作次数

思路:

当字符串中全是c的时候操作就是0次,当字符串中由一个数x满足n/x=1,并且这个位置时c,则只需要一次,因为n/x=1表示1~n中只有一个x的倍数,就是x本身,其他情况都可以通过n和n-1两次操作转化

题解:

#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
const int mod=1e9+7;
void solve() {
    int n;
    char c;
    cin>>n>>c;
    string s;
    cin>>s;
    bool ok=true;
    int cnt=0;
    for(auto i:s){
        if(i!=c) ok=false,cnt++;
    }
    if(ok){
        cout<<0<<endl;
        return;
    }
    if(s[n-1]!=c and cnt==1){
        cout<<1<<endl;
        cout<<n-1<<endl;
        return;
    }
    if(s[n-1]==c and cnt){
        cout<<1<<endl;
        cout<<n<<endl;
        return;
    }
    for(int i=0;i<n;i++){
        if(n/(i+1)<=1 and s[i]==c) {
            cout<<1<<endl;
            cout<<i+1<<endl;
            return;
        }
    }
    cout<<2<<endl;
    cout<<n<<' '<<n-1<<endl;
}
signed main() {
    ios::sync_with_stdio(false);cin.tie(0);
    int _; cin >> _; while (_--) 
    solve();
    return 0;
}

D

D

题意:

由n个玩家,m个回合,每个回合包括两次玩家u和v,和一个字符串,表示u说v时imposter或者crewmate,假如u时crewmate一定说的是真话,imposter一定说的是假话,求解最大可能的imposter数量或者判定这些话中有矛盾

思路:

判定有矛盾可以使用扩展域并查集来进行,比如u说v是imposter,这里先假设u是crewmate,那么表示v在说谎,把v的crewmate域和u的imposter域合并,把v的imposter域和u的crewmate合并,假如在未合并前发现,u的imposter域和v的imposter域有共同的根节点,则表明有矛盾,或者说最后看每个玩家的imposter域和crewmate域有没有连通,连通表示有矛盾,判断数量的话,可以使用维护每个域的size,然后找到根节点中imposter域和crewmate中最大的加上,因为可以判断他有没有矛盾,但不能说某个玩家一定是哪个域里的

题解:

#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
const int N = 2000100;
int p[N * 3];
int s[N * 3];
int find(int x) {
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}
void merge(int a, int b) {
    int pa = find(a), pb = find(b);
    if (pa != pb) {
        p[pb] = pa;
        s[pa] += s[pb];
    }
}
int vis[N];
void solve() {
    int n, m;
    cin >> n >> m;
    int  u, v;
    string str;
    for (int i = 1; i <= 2 * n; i++) p[i] = i, s[i] = i <= n;//两个域只需要一个域赋值即可;
    bool ok = true;
    int tem = m;
    while (m--) {
        cin >> u >> v >> str;
        int u_i = u, u_c = u + n;
        int v_i = v, v_c = v + n;
        if (str == "imposter") {
            if (find(u_c) == find(v_c)) {
                ok = false;
            }
            merge(u_c, v_i);
            merge(u_i, v_c);

        } else {
            if (str == "crewmate") {
                if (find(u_c) == find(v_i)) {
                    ok = false;
                }
                merge(u_c, v_c);
                merge(u_i, v_i);
            }
        }
    }
    if (!ok) {
        cout << -1 << endl;
        return;
    }
    int mmax = 0;
    for (int i = 1; i <= n; i++) {
        if (p[i] == i) mmax += max(s[i], s[i + n]);
    }
    if (tem == 0) mmax = n;
    cout << mmax << endl;

}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int _; cin >> _; while (_--)
        solve();
    return 0;
}

E1

E1

题意:

给定2k-1个节点,一共6种颜色,每个节点需要染色,并且遵循以下规则:
a white node can not be neighboring with white and yellow nodes;
a yellow node can not be neighboring with white and yellow nodes;
a green node can not be neighboring with green and blue nodes;
a blue node can not be neighboring with green and blue nodes;
a red node can not be neighboring with red and orange nodes;
an orange node can not be neighboring with red and orange nodes;

思路:

根节点有6种染色方法,字节点就是4种,当前子节点的一个子节点也是4种,样例就是6x4x4x4x4x4x4=24576,解法有很多种,这里写一个记忆化dfs

题解:

#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
int f[100];
int res=6;
const int mod=1e9+7;
int dfs(int u){
    if(u==1) return 4;
    if(f[u]) return f[u]%mod;
    f[u]=((dfs(u-1)%mod*dfs(u-1)%mod)%mod*4)%mod;
    return f[u]%mod;
}
int qmi(int a,int b,int p){//快速幂
    int res=1%p;
    while(b){
        if(b&1) res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
void solve() {
    int k;
    cin>>k;
    int cur=dfs(k);
    int mod2=qmi(2,mod-2,mod);
    cout<<(cur*mod2%mod*3%mod)%mod<<endl;
}
signed main() {
    ios::sync_with_stdio(false);cin.tie(0);
    //int _; cin >> _; while (_--) 
    solve();
    return 0;
}
posted @ 2021-10-09 17:14  指引盗寇入太行  阅读(114)  评论(0编辑  收藏  举报