1. 程式人生 > >牛客小白月賽9

牛客小白月賽9

A題  費馬小 + 概率

每次輸入a b之後求反 算出這一層不扔的 概率    所有層不仍的概率相乘之後  再用1-   即得到被砸的概率

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;

ll quickPow(ll a,ll b)
{
    ll res = 1;
    while(b){
        if(b&1)
            res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
ll inv(ll k)
{
    return quickPow(k,mod-2);
}

int main()
{
    ll n,a,b;
    ll ans = 1;
    cin >> n;
    for(int i = 1;i <= n;i ++){
        cin >> a >> b;
        ll t = (b - a + mod) % mod;
        ans = (ans * t % mod * inv(b)) % mod;
    }
    cout << (1 - ans + mod) % mod;
    return 0;
}

B題 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int main()
{
    int T;
    cin >>T;
    while(T --){
        ll n;
        cin >> n;
        if(n == 1 || n == 2)
            cout << 1 << endl;
        else
            cout << 0 << endl;
    }
    return 0;
}

C題

資料不強的結果就是暴力模擬可過

ps:時間給了3s

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int a[N],n,m;
int main()
{
    int op,l,r,k;
    cin >> n >> m;
    for(int i = 1;i <= n;i ++)
        cin >> a[i];
    while(m --){
        cin >> op >> l >> r;
        if(op == 1){
            ll s = 0;
            for(int i = l;i <= r;i ++)
                s += a[i];
            cout << s << '\n';
        }else{
            cin >> k;
            for(int i = l;i <= r;i ++)
                a[i] ^= k;
        }
    }
    return 0;
}

線段樹

#include<bits/stdc++.h>
using namespace std;
#define MAXN 131072
#define ll long long
ll ans;
int n,q,i,j,k,l,a[MAXN],t[17][MAXN<<1],s[17][MAXN<<1],o[17][MAXN<<1];
void up(int d,int R)
{
    t[d][R]=t[d][R<<1]+t[d][R<<1|1];
    if(s[d][R])t[d][R]=o[d][R]-t[d][R];
}
void build(int d,int R,int l,int r)
{
    o[d][R]=r-l+1;
    if(l==r)
    {
        t[d][R]=a[l]>>d&1;
        return;
    }
    int mid=l+r>>1;
    build(d,R<<1,l,mid);
    build(d,R<<1|1,mid+1,r);
    up(d,R);
}
void fix(int d,int R,int l,int r,int l1,int r1)
{
    if(l1<=l&&r<=r1)
    {
        s[d][R]=!s[d][R];
        t[d][R]=o[d][R]-t[d][R];
        return;
    }
    int mid=l+r>>1;
    if(l1<=mid)fix(d,R<<1,l,mid,l1,r1);
    if(r1>mid)fix(d,R<<1|1,mid+1,r,l1,r1);
    up(d,R);
}
int ask(int d,int R,int l,int r,int l1,int r1)
{
    if(l1<=l&&r<=r1)return t[d][R];
    int mid=l+r>>1,x=0;
    if(l1<=mid)x=ask(d,R<<1,l,mid,l1,r1);
    if(r1>mid)x+=ask(d,R<<1|1,mid+1,r,l1,r1);
    if(s[d][R])x=min(r,r1)-max(l,l1)+1-x;
    return x;
}
int main()
{
    scanf("%d%d",&n,&q);
    for(i=1;i<=n;i++)scanf("%d",a+i);
    for(i=0;i<17;i++)build(i,1,1,n);
    while(q--)
    {
        scanf("%d%d%d",&i,&j,&k);
        if(i==1)
        {
            for(ans=l=0;l<17;l++)ans+=((ll)ask(l,1,1,n,j,k))<<l;
            cout<<ans<<endl;
        }
        else
        {
            scanf("%d",&i);
            for(l=0;l<17;l++)if(i>>l&1)fix(l,1,1,n,j,k);
        }
    }
    return 0;
}

E題

暴力也可過,是出題人減弱資料了? 還是小白賽的套路。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int a[N],n,m;
int main()
{
    int l, r, k;
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++)
        scanf("%d",&a[i]);

    while(m --){
        scanf("%d%d%d",&l,&r,&k);
        int cnt = 0;
        for(int i = l;i <= r;i ++)
            if(a[i] <= k)
                cnt ++;
        cout << cnt << '\n';
    }
    return 0;
}

樹狀陣列維護

分別記錄資料和詢問的x

從小到大排序

一遍維護

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
struct node{
    int x,id,l,r;
};
int n,m,tree[N],ans[N];
node a[N],b[N];
bool cmp(node c,node d)
{
    return c.x < d.x;
}
int lowbit(int k)
{
    return k&-k;
}
int sum(int k)
{
    int ans = 0;
    while(k){
        ans += tree[k];
        k -= lowbit(k);
    }
    return ans;
}
void update(int k,int v)
{
    while(k <= n){
        tree[k] += v;
        k += lowbit(k);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i ++){
        scanf("%d",&a[i].x);
        a[i].id = i;
    }
    sort(a + 1,a + n + 1,cmp);
    for(int i = 1;i <= m;i ++){
        scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].x);
        b[i].id = i;
    }
    sort(b + 1,b + m + 1,cmp);
    int p = 1;
    for(int i = 1;i <= m;i ++){

        while(a[p].x <= b[i].x && p <= n){
            update(a[p].id,1);
            p ++;
        }
        ans[b[i].id] = sum(b[i].r) - sum(b[i].l-1);
    }
    for(int i = 1;i <= m;i ++)
        cout << ans[i] << '\n';
    return 0;
}

H題

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int main()
{
    ll n;
    cin >> n;
    if(n == 1)
        cout << 2;
    else
        cout << 2 * n - 1;
    return 0;
}