Codeforces 979 字符串强制N变换最多出现字母 DFS子树 暴力01字典树

A

/* Huyyt */
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
#define pb push_back
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int N = 2e5 + 5;
int main()
{
        ll n;
        cin >> n;
        if (n == 0)
        {
                cout << 0 << endl;
                return 0;
        }
        n++;
        if (n % 2 == 0)
        {
                cout << n / 2 << endl;
        }
        else
        {
                cout << n << endl;
        }
}
View Code

B

/* Huyyt */
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
#define pb push_back
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int N = 2e5 + 5;
string a, b, c;
string str[5];
int num[5][1000];
int ansermaxn[5];
int main()
{
        ll n;
        cin >> n;
        for (int i = 1; i <= 3; i++)
        {
                cin >> str[i];
        }
        int aim = 0;
        int ansermax = -1;
        int ansnow;
        for (int i = 1; i <= 3; i++)
        {
                for (int j = 0; j < str[i].size(); j++)
                {
                        num[i][str[i][j]]++;
                }
        }
        for (int i = 1; i <= 3; i++)
        {
                for (int j = 65; j <= 122; j++)
                {
                        if (num[i][j] + n <= str[i].size())
                        {
                                ansnow = num[i][j] + n;

                                if (ansnow > ansermax)
                                {
                                        aim = i;
                                        ansermax = ansnow;
                                }
                        }
                        else
                        {
                                if (num[i][j] == str[i].size())
                                {
                                        if (n == 1)
                                        {
                                                ansnow = str[i].size() - 1;
                                        }
                                        else
                                        {
                                                ansnow = str[i].size();
                                        }
                                }
                                else
                                {
                                        ansnow = str[i].size();
                                }
                                if (ansnow > ansermax)
                                {
                                        aim = i;
                                        ansermax = ansnow;
                                }
                        }
                        ansermaxn[i] = max(ansermaxn[i], ansnow);
                }
        }
        int cnt = 0;
        for (int i = 1; i <= 3; i++)
        {
                //cout << ansermaxn[i] << endl;
                if (ansermaxn[i] == ansermax)
                {
                        cnt++;
                }
        }
        if (cnt > 1)
        {
                cout << "Draw" << endl;
                return 0;
        }
        if (aim == 1)
        {
                cout << "Kuro" << endl;
        }
        else if (aim == 2)
        {
                cout << "Shiro" << endl;
        }
        else
        {
                cout << "Katie" << endl;
        }
}
View Code

C

/* Huyyt */
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
#define pb push_back
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int N = 3e5 + 5;
vector<int> gra[N];
ll anser = 0;
ll reduce = 0;
ll number1 = 0;
ll number2 = 0;
ll number = 0;
int flag = 0;
void dfs(int x, int pre, int aim, int flag)
{
        if (flag)
        {
                number++;
        }
        int len = gra[x].size();
        for (int i = 0; i < len; i++)
        {
                int to = gra[x][i];
                if (to == pre)
                {
                        continue;
                }
                if (to == aim)
                {
                        dfs(to, x, aim, 1);
                }
                else
                {
                        dfs(to, x, aim, flag);
                }
        }
}
int main()
{
        int n;
        cin >> n;
        int x, y;
        int u, v;
        cin >> x >> y;
        for (int i = 1; i <= n - 1; i++)
        {
                scanf("%d %d", &u, &v);
                gra[u].pb(v);
                gra[v].pb(u);
        }
        anser = 1LL * (n - 1) * n;
        dfs(x, -1, y, 0);
        number1 = number;
        number = 0;
        dfs(y, -1, x, 0);
        number2 = number;
        anser -= 1LL * number2 * number1;
        cout << anser << endl;
}
View Code

D

一开始给你一个空的集合

有两种操作:

①集合中加入一个数字X 

②询问给你三个数字Xi Ki Si 查找集合中是否存在数字V满足 ① Ki是Xi和V的因子 ② V<=Si-Ki 当如果有多个满足条件的数输出Xi Xor V最大的那个V

解:

01字典树暴力操作

直接每次insert一个未出现过的数的时候 暴力Insert到每个它的因子里面去

复杂度为:1e5*ln(1e5)*位数(最多为18)=1e7

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
vector<int>G[maxn];
int vis[maxn];
void read(int &x)
{
        x = 0;
        char c = getchar();
        while (c > '9' || c < '0')
        {
                c = getchar();
        }
        while (c >= '0' && c <= '9')
        {
                x = (x << 3) + (x << 1) + c - '0', c = getchar();
        }
}
struct Trie //01字典树指针版
{
        struct node
        {
                int Min, val;
                node *ch[2];
                node()
                {
                        Min = maxn; //维护一个最小值
                        ch[0] = ch[1] = NULL;
                }
        }*rt[maxn]; 
        void init()
        {
                for (int i = 1; i < maxn; i++)
                        for (int j = i; j < maxn; j += i) //复杂度1e5*ln1e5=1e6
                        {
                                G[j].push_back(i); //把一个数的因子全部push进去
                        }
                for (int i = 1; i < maxn; i++)
                {
                        rt[i] = new node; //每个数赋予一个新指针
                }
        }
        void insert(int x)
        {
                int Len = G[x].size();  //插入一个数
                for (int i = 0; i < Len; i++)  
                {
                        node *cur = rt[G[x][i]];  //暴力枚举insert到这个数的每个因子里面取
                        cur->Min = min(cur->Min, x);  //维护最小值
                        for (int j = 17; j >= 0; j--)  //争取取每位^1的使之异或值最大
                        {
                                if (cur->ch[x >> j & 1] == NULL) //如果没有的话创造一个新节点
                                {
                                        cur->ch[x >> j & 1] = new node;
                                }
                                cur = cur->ch[x >> j & 1];
                                cur->Min = min(cur->Min, x);  //每个节点维护最小值
                        }
                        cur->val = x; //最后一个节点的值为x 最后取答案用
                }
        }
        int query(int x, int k, int s)
        {
                if (x % k != 0)  //如果k是x和v的gcd的因子的话 x和v都是k的倍数
                {
                        return -1;
                }
                node *cur = rt[k]; //
                if (cur->Min > s - x)  //如果最小的都不能满足的话 不存在
                {
                        return -1;
                }
                for (int i = 17; i >= 0; i--)
                {
                        int tb = x >> i & 1;
                        if (cur->ch[tb ^ 1] != NULL && cur->ch[tb ^ 1]->Min <= s - x) //如果^1的值满足条件
                        {
                                cur = cur->ch[tb ^ 1];
                        }
                        else
                        {
                                cur = cur->ch[tb];
                        }
                }
                return cur->val; //返回使之异或值最大的数列值
        }
} T;
int main()
{
        int N, i, j, opt, x, k, s;
        T.init();
        read(N);
        while (N--)
        {
                read(opt);
                if (opt == 1)
                {
                        read(x);
                        if (!vis[x])
                        {
                                vis[x] = 1, T.insert(x);
                        }
                }
                else
                {
                        read(x);
                        read(k);
                        read(s);
                        printf("%d\n", T.query(x, k, s));
                }
        }
        return 0;
}
View Code

 

posted @ 2018-05-15 10:26  Aragaki  阅读(247)  评论(0编辑  收藏  举报