本蒟蒻这次只过了三题 赛后学习了一下出题人巨佬的标码(码风比我好多了 贴的代码有些是仿出题人)
现在将自己的理解写下来与大家分享

A
这个题一分析就是每个数字都会与所有数字&一下 (a&a=a)
&字操作是二进制同位都为一才为一 这时解法就变成统计每个二进制位上1的次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = 1e5;
const ll maxm = 30;
ll res;
ll arr[maxn + 5], n, cnt[maxm + 5];
 
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)scanf("%d", &arr[i]);
    for (int i = 1; i <= n; ++i)
        for (int j = 0; j < 30; ++j)
            if (arr[i] & (1 << j))cnt[j] += 1;///各位上1的个数
    for (int i = 0; i < 30; ++i)res +=  cnt[i] * cnt[i] * (1 << i);
    printf("%lld\n", res);
    return 0;
}

B
简单的n2枚举 分析一下可以知道每条边都用了n-2次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,ans;
ll mod=998244353;
struct P
{
    ll x,y;
}a[110];
ll len(P m,P n)
{
    return abs(m.x-n.x)+abs(m.y-n.y);
}
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;++i)scanf("%lld%lld",&a[i].x,&a[i].y);
    for(int i=1;i<=n;++i)
    {
        for(int j=i+1;j<=n;++j)
        {
           ans+=(len(a[i],a[j])*(n-2))%mod;
        }
    }
    cout<<ans%mod<<endl;
    return 0;
}

C
这是一个比较基础的dp方程的进阶 从n个物品中选k个
dp[i][j]=dp[i-1][j]+dp[i-1][j-1]
i表示到第几个字符了 j是用了几个字符
dp[i-1][j]是不用这个新加的 dp[i-1][j-1]是用这个新加的
这题的关键点是我们这样计算重复了多少字符(本质不同的解释)
其实仔细一想 我们重复计算就是相当于把 输出前面出现的那个符号在那里又多算了一次
多了哪一部分 这个重复符号上次出现的位置的dp值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<bits/stdc++.h>
#define ll long long
using namespace std;
 
const ll maxn = 1000;
const ll mod = 1e9 + 7;
 
ll dp[maxn + 5][maxn + 5];
 
ll n, k, pre[maxn + 5];///pre记录上次同一个字符的出现位置
char s[maxn + 5];
 
int main()
{
    scanf("%d %d", &n, &k);
    scanf("%s", s + 1);
    dp[0][0] = 1;///n中选0个为1种情况
    for (int i = 1; i <= n; ++i) {
        dp[i][0] = 1;
        for (int j = 1; j <= i; ++j) {
            dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];
            if (pre[s[i] - 'a'])dp[i][j] -= dp[pre[s[i] - 'a'] - 1][j - 1];
            dp[i][j] %= mod;
        }
        pre[s[i] - 'a'] = i;
    }
    ll res = dp[n][k];
    if (res < 0)res += mod;
    printf("%lld\n", res);
    return 0;
}

D
这题由于蒟蒻(我)追求梦想用n2枚举过了 但赛后还是写了一下正解方程(n枚举应该可以过)
写这题你需要一个 扩展欧几里得模板(能判断是否有整数解) 然后枚举一个数就把题目变成了一个模板题了 前面是n2枚举 后面大概是正解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,c,k,minl;
int main()
{
    cin>>a>>b>>c>>k;
    minl=min(a,min(b,c));
    ll s=k/minl;
    for(int i=1;i<=s;++i)
    {
        for(int j=1;j<=s;++j)
        {
            ll z1=k-a*i-b*j;
            ll z2=k-b*i-c*j;
            ll z3=k-a*i-c*j;
            if(z1%c==0){cout<<i<<" "<<j<<" "<<z1/c;return 0;}
            if(z2%a==0){cout<<z2/a<<" "<<i<<" "<<j;return 0;}
            if(z3%b==0){cout<<i<<" "<<z3/b<<" "<<j;return 0;}
        }
    }
    return 0;
}
 
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,c,k;
void exgcd(ll a,ll b,ll&x,ll&y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return;
    }
    exgcd(b,a%b,x,y);
    ll t=x;
    x=y;
    y=t-(a/b)*y;
}
 
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
 
int main()
{
    scanf("%lld%lld%lld%lld",&a,&b,&c,&k);
    for(ll i=0;i<=k/c;i++){
        ll d=k-i*c;
        ll x,y;
        exgcd(a,b,x,y);
        ll e=gcd(a,b);
        if(d%e!=0continue;///有无解
        ll n=d/e;
        ll m=b/e;
        x*=n;y*=n;
        x=(x%m+m)%m;
        y=(d-x*a)/b;///有无整数解
        if(x>=0&&y>=0){
            printf("%lld %lld %lld",x,y,i);
            return 0;
        }
    }
    return 0;
 }

F
这题作为正在学习计算几何的蒟蒻(我) 那肯定是要学习的
做这题的关键是要注意画图才能理解 代码里大部分有注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include<bits/stdc++.h>
#define lowbit(x) x&(-x)
#define ll long long
using namespace std;
typedef pair<int,int> pii;
 
const int maxn=1e5+7;
const int pi=acos(-1.0);
const double eps=1e-9;
 
int read()///快读
{
    int x=0,f=1;char s=getchar();
    for( ;!isdigit(s);s=='-' && (f=-1),s=getchar());
    for( ;isdigit(s);x=x*10+s-48,s=getchar());
    return x*f;
}
 
struct point
{
    int x,y,tag;
    point( ) { x=y=tag=0; }
    point( ll _x,ll _y )
    {
        x=_x,y=_y;
    }
    bool operator==( const point& rhs ) const {
        return x==rhs.x && y==rhs.y;
    }
    point operator -(const point &rhs ) const {
        return point(x-rhs.x,y-rhs.y);
    }
    point operator+( const point &rhs ) const {
        return point(x+rhs.x,y+rhs.y);
    }
    ll operator * ( const point &rhs ) const /// 叉积
        return 1ll*x*rhs.y-1ll*y*rhs.x;
    }
    ll dot( const point &rhs ) const /// 点积
        return 1ll*x+rhs.x+1ll*y*rhs.y;
    }
    void get() { x=read(),y=read(); }
}O,p[maxn],w1[maxn],w2[maxn],A,B;
int n,m1,m2;
 
inline bool cmpA( point a,point b ) { return (a-A)*(b-A)>0; }
inline bool cmpB( point a,point b ) { return (a-B)*(b-B)>0; }
 
int c[maxn];
ll ans=0;
void add( int x ) { while( x<n ) c[x]++,x+=lowbit(x); }
int query( int x ,int tt=0 ) { while( x ) tt+=c[x],x-=lowbit(x);return tt;}
 
void solve( point *t,int m )
{
    sort(t+1,t+1+m,cmpA);///以A点极角排序
    ans+=(1ll*m*(m-1))>>1;///先假设所有点对都能与线段相交
    forint i=1;i<=m;i++ ) t[i].tag=i;
    sort(t+1,t+m+1,cmpB);///以B点极角排序
    memset(c,0,sizeof(c));
    forint i=1;i<=m;i++ )///减去不能与线段相交的点对
    {
        ///这里假设线段点为P、Q  选出来的点对为 A、B  在画图过程中发现
        ///选出来的能交的点对        B点要以P排序在A前面而且以Q排序也要在A前面
        ///不是就减去   以树状数组解决这个区间问题
        ans-=query(t[i].tag);
        add(t[i].tag);
    }
}
 
int main()
{
    n=read(),A.get(),B.get();
    forint i=1;i<=n;i++ ) p[i].get();
    forint i=1;i<=n;i++ )
    {
        if( (A-p[i])*(B-p[i])>0ll ) w1[++m1]=p[i];///利用叉积把点分为线段上下两部分
        else w2[++m2]=p[i];
    }
    solve(w1,m1);///第一种情况  两个点在同一侧
    solve(w2,m2);
 
    ans+=1ll*m1*m2;///第二种情况 两个点在不同侧  还是一样先假设所有点对都能与线段相交
 
    sort(w1+1,w1+m1+1,cmpA);///一样 以A点极角排序
    sort(w2+1,w2+m2+1,cmpA);
    forint i=1,bas=1;i<=m1;i++ )///减去不能与线段相交的点对
    {
        ///i 上侧   bas 下侧
        ///画图分析
        while( bas<=m2 && (w1[i]-A)*(w2[bas]-A)>0 ) ++bas;///叉积判断
        ans-=bas-1;
    }
 
    sort(w1+1,w1+m1+1,cmpB);///以B点极角排序
    sort(w2+1,w2+m2+1,cmpB);
    forint i=1,bas=1;i<=m2;i++ )
    {
        ///一样
        while( bas<=m1 && (w2[i]-B)*(w1[bas]-B)>0 ) ++bas;
        ans-=bas-1;
    }
    printf("%lld\n",ans);
    return 0;
}

e题的题解可能在我大佬队友写完后贴出来(这个方向我是真不会).....
看到最后的彩蛋 推荐纯音乐 Like Sunday,Like Rain ^-^

牛客练习赛60 A—F题解(缺E题)的更多相关文章

  1. 牛客练习赛60 E 旗鼓相当的对手

    LINK:旗鼓相当的对手 考场上遇到这种简单的树形dp优化题目我真的不一定能写出来.. 虽然这道题思路很简单 设f[i][j]表示距i距离为j的点的个数 g[i][j]表示距i距离为j的点权和. 可以 ...

  2. 牛客练习赛69 火柴排队 题解(dp)

    题目链接 题目大意 给你一个长为n(n<=5e3)的数组a.随机使得k个元素增加d.要你求多大的概率使得,这些数组元素的相对大小不发生改变 输出 n 行每行一个整数,第 i 行的整数表示 k=i ...

  3. 牛客练习赛60 D 斩杀线计算大师

    LINK:斩杀线计算大师 给出a,b,c三个值 求出 ax+by+cz=k的x,y,z的正整数解 保证一定有解. 考虑两个数的时候 ax+by=k 扩展欧几里得可以解决. 三个数的时候 一个暴力的想法 ...

  4. 牛客练习赛71 数学考试 题解(dp)

    题目链接 题目大意 要你求出有多少个长度为n的排列满足m个限制条件 第i个限制条件 p[i]表示前 p[i]个数不能是1-p[i]的排列 题目思路 这个感觉是dp但是不知道怎么dp 首先就是要明白如果 ...

  5. 牛客练习赛66 C公因子 题解(区间gcd)

    题目链接 题目大意 给你一个长为n的数组,给所有数组元素加上一个非负整数x,使得这个数组的所有元素的gcd最大 题目思路 这主要是设计到一个多个数gcd的性质 gcd(a,b,c,d.....)=gc ...

  6. 牛客练习赛64 D【容斥+背包】

    牛客练习赛64 D.宝石装箱 Description \(n\)颗宝石装进\(n\)个箱子使得每个箱子中都有一颗宝石.第\(i\)颗宝石不能装入第\(a_i\)个箱子.求合法的装箱方案对\(99824 ...

  7. 牛客练习赛31 D 神器大师泰兹瑞与威穆 STL,模拟 A

    牛客练习赛31 D 神器大师泰兹瑞与威穆 https://ac.nowcoder.com/acm/contest/218/D 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 26214 ...

  8. 最小生成树--牛客练习赛43-C

    牛客练习赛43-C 链接: https://ac.nowcoder.com/acm/contest/548/C 来源:牛客网 题目描述 ​ 立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 ...

  9. 牛客练习赛26:D-xor序列(线性基)

    链接:牛客练习赛26:D-xor序列(线性基) 题意:小a有n个数,他提出了一个很有意思的问题:他想知道对于任意的x, y,能否将x与这n个数中的任意多个数异或任意多次后变为y 题解:线性基 #inc ...

随机推荐

  1. curator配置及使用

    1.action.yml --- actions: 1: action: index_settings options: index_settings: index: routing.allocati ...

  2. iOS自动化登录测试demo

    <软件自动化测试开发>出版了 测试开发公开课培训大讲堂 微信公众号:测试开发社区 测试开发QQ群:173172133 咨询QQ:7980068 咨询微信:zouhui1003it

  3. Python Mock 的入门

    Mock是什么 Mock这个词在英语中有模拟的这个意思,因此我们可以猜测出这个库的主要功能是模拟一些东西.准确的说,Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代 ...

  4. 【Java】macOS下编译JDK8

    安装mercurial brew install mercurial 下载源码 1234 hg clone http://hg.openjdk.java.net/jdk8/jdk8 java-sour ...

  5. Ta说:2016微软亚洲研究院第二届博士生论坛

    ​ "聚合多元人才创造无尽可能,让每一位优秀博士生得到发声成长机会"可以说是这次微软亚洲研究院博士生论坛最好的归纳了.自去年首次举办以来,这项旨在助力青年研究者成长的项目迅速得到了 ...

  6. Redis(2)——跳跃表

    一.跳跃表简介 跳跃表(skiplist)是一种随机化的数据结构,由 William Pugh 在论文<Skip lists: a probabilistic alternative to ba ...

  7. python 生成随机数、生成 uuid

    1. 使用 uuid.uuid1 产生一个随机数 2. 在使用 random.sample() 产生一个随机字符串 3. 将两者进行拼接 import uuid import random def r ...

  8. 前端javascript知识(一)

    介绍一下 JS 的基本数据类型. Undefined.Null.Boolean.Number.String 介绍一下 JS 有哪些内置对象. Object 是 JavaScript 中所有对象的父对象 ...

  9. linux 安装 memcached

    1.Linux系统安装memcached,首先要先安装libevent库. yum install libevent libevent-deve 2.安装memcached yum install - ...

  10. 2020 新个税算的头疼?会 python,这都不是事儿...

    背景 今年疫情复工后,财务小姐姐给我们普及了2020年新个税的算法.. 听完之后的感觉就是:恩,原来是这么回事! 虽然是个小工薪阶级,但是对于扣多少税还是很关心的.于是拿起笔算了算2月份的个税,产生了 ...