练习

今天没事把去年浙江省赛题做了做,2个半小时 是个分界线,出8道后就一直划水了。菜鸡一个
A
水题
B
题意:找有多少对(a, b)使得a Xor b > max(a, b)

考虑高位的1,扫一遍就好了。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<vector>
#include<map>
#define CLR(a, b) memset(a, (b), sizeof(a))
using namespace std;
const int MAXN = 1e5 + 10;
typedef long long LL;
int a[MAXN];
int bit[40], len, num[40];
void get(int n) {
    len = 0;
    while(n) {
        bit[len++] = n % 2;
        n /= 2;
    }
}
int main()
{
    int t; scanf("%d", &t);
    while(t--) {
        int n; scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        CLR(num, 0); sort(a+1, a+n+1);
        LL ans = 0;
        for(int i = 1; i <= n; i++) {
            get(a[i]);
            for(int j = 0; j < len; j++) {
                if(bit[j] == 0) {
                    ans += num[j];
                }
            }
            num[len-1]++;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

C
懵懂

D
题意:求序列所有连续子序列的(去重后)元素和。

思路:考虑每一个元素的贡献,a[i]的贡献为(i - s) * (n - i + 1) * a[i],其中s-1是上一个a[i]元素出现的位置,扫描一遍就OK了。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<vector>
#include<map>
#define CLR(a, b) memset(a, (b), sizeof(a))
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
int vis[MAXN], a[MAXN];
int main()
{
    int t; scanf("%d", &t);
    while(t--) {
        int n; scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            vis[a[i]] = 0;
        }
        LL ans = 0;
        for(int i = 1; i <= n; i++) {
            if(vis[a[i]] > 0) {
                ans += 1LL * (i - vis[a[i]]) * (n - i + 1) * a[i];
            }
            else {
                ans += 1LL * i * (n - i + 1) * a[i];
            }
            vis[a[i]] = i;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

EF神题
GH水题
I过不了
J模拟
K模拟
并没有什么坑点
AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<vector>
#include<map>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define eps 1e-5
using namespace std;
typedef long long LL;
bool vis[110][110][20];
int Map[110][20];
struct Node {
    double score;
    int id;
};
Node team[110];
bool cmp(Node a, Node b) {
    return a.score > b.score;
}
bool cmp1(Node a, Node b) {
    return a.id < b.id;
}
int main()
{
    int t; scanf("%d", &t);
    while(t--) {
        int n, p, s, q; scanf("%d%d%d%d", &n, &p, &s, &q);
        for(int i = 1; i <= n; i++) {
            team[i].score = s; team[i].id = i;
            for(int j = 1; j <= p; j++) {
                Map[i][j] = 1;
            }
        }
        while(q--) {
            int N; scanf("%d", &N); CLR(vis, false);
            int rec[110][20][110], num[110][20];
            bool attacked[110][20];
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= p; j++) {
                    attacked[i][j] = false;
                    num[i][j] = 0;
                }
            }

            while(N--) {
                int x, y, z;
                scanf("%d%d%d", &x, &y, &z);
                if(vis[x][y][z]) continue;

                attacked[y][z] = true;
                rec[y][z][num[y][z]] = x;
                num[y][z]++;

                vis[x][y][z] = true;
                Map[y][z] = 0;
            }
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= p; j++) {
                    if(attacked[i][j]) {
                        team[i].score -= n - 1;
                        double total = n - 1;
                        double add = total / num[i][j];
                        for(int k = 0; k < num[i][j]; k++) {
                            team[rec[i][j][k]].score += add;
                        }
                    }
                }
            }
//            for(int i = 1; i <= n; i++) {
//                printf("%.5lf %d\n", team[i].score, team[i].id);
//            }
            for(int i = 1; i <= p; i++) {
                for(int j = 1; j <= n; j++) {
                    int v; scanf("%d", &v);
                    Map[j][i] = v;
                }
            }
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= p; j++) {
                    if(Map[i][j] == 0) {
                        team[i].score -= n - 1;
                        int cnt = 0;
                        for(int k = 1; k <= n; k++) {
                            if(Map[k][j] && k != i) {
                                cnt++;
                            }
                        }
                        double add = (n - 1) * 1.0 / cnt;
                        for(int k = 1; k <= n; k++) {
                            if(Map[k][j] && k != i) {
                                team[k].score += add;
                            }
                        }
                    }
                }
            }
            sort(team + 1, team + n + 1, cmp);
            int M; scanf("%d", &M);
            while(M--) {
                int index; scanf("%d", &index);
                int Rank = 1;
                for(int i = 1; i <= n; i++) {
                    if(i == 1 || (team[i-1].score - team[i].score) > eps) {
                        Rank = i;
                    }
                    if(team[i].id == index) {
                        if(i == 1 || (team[i-1].score - team[i].score) < eps) {
                            printf("%.5lf %d\n", team[i].score, Rank);
                        }
                        else {
                            printf("%.5lf %d\n", team[i].score, i);
                        }
                        break;
                    }
                }
            }
            sort(team + 1, team + n + 1, cmp1);
        }
    }
    return 0;
}

L水题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值