101Hack44

1001——Picking Numbers

Picking Numbers题目
水题,差小于1的两个数的个数最大

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int arr[110];
int main() {
    int n,data;
    scanf("%d",&n);
    for(int i = 0;i<n;i++) {
        scanf("%d",&data);
        arr[data]++;
    }
    int ans = arr[0];
    for(int i = 0;i<100;i++) ans =max(ans,arr[i]+arr[i+1]);
    printf("%d\n",ans);
    return 0;
}

1002——Alice and Bob’s Silly Game

Alice and Bob’s Silly Game题目
博弈的问题,给你n个数,每次可以选择一个素数,将素数和素数的倍数的数删除,如果不能删除则为输。我们会发现这个题的本质就是给你小于的n的素数,每次可以从中选择一个素数删除,直到不能删除为止。那么如果素数的个数为奇数则Alice赢,否则Bob赢。

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e5+100;
int vis[maxn];
void Get() {
    memset(vis,1,sizeof(vis));
    vis[0] = vis[1] = 0;
    for(int i = 2;i<maxn;i++) {
        if(vis[i]) {
            for(int j = i+i;j<maxn;j+=i) vis[j] = 0;
        }
    }
    for(int i = 0;i<maxn;i++) vis[i] = vis[i]+vis[i-1];
}
int main() {
    Get();
    int n,T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        if(vis[n]&1) printf("Alice\n");
        else printf("Bob\n");
    }
    return 0;
}

1003——Expected Tree Leaves

Expected Tree Leaves题目
将节点从小到大放置,每次选择一个小的节点放在他的后面,问形成的树的叶子节点的个数的期望
我们计算第i个节点为叶子节点的期望,那么我们假设 i 为叶子节点,那么第 i+1 的节点的概率为 i1i ,第 i+2 的节点的概率为 ii+1 ,那么第 i 个节点为叶子的概率为 Pi=i1i×ii+1++n2n1=i1n1 ,所以 E=i=2n=1n1+2n1++n1n1=i=1n1n1=n×(n1)2n1=n2 ,所以 ans=n2×n!

#include <bits/stdc++.h>

using namespace std;
const int mod = 1e9+7;
typedef long long LL;
int main() {
    int n;
    LL ans;
    scanf("%d",&n);
    ans = n;
    for(int i = 3;i<=n;i++) ans = (ans*i)%mod;
    printf("%lld\n",ans);
    return 0;
}

1004——Palindromic Subsets

Palindromic Subsets 题目
给你一个字符串,有两种操作,一种是对于区间[L,R]中的字符,向后移动T个字符既 Ci=(Ci+26)%26 ,第二种操作是询问区间[L,R]可以组成多少个回文串
对于一个区间,我们对于第一种操作,可以通过线段树实现,那么对于第二种操作,我们假设已经知道区间[L,R]种每一个字符的个数 Numi 0i25 ,对于一个字母 i 可以组成多少个回文串呢?显然是 2Numi 个,其中长度为奇数和偶数的个数相同均为 2Numi1 种。显然最后组成的回文串分为两种,一种是长度为奇数的,一种是长度为偶数的。对于长度为偶数的,答案就是多有字符组成长度为偶数的个数的乘积,奇数就是我们枚举长度为奇数的字符串,那么答案就是非枚举字符的偶数的乘积与枚举字符的奇数乘积。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+100;
const int mod = 1e9+7;
struct node {
    int lazy;
    int num[26];
    void Clear() {
        lazy = 0;
        memset(num,0,sizeof(num));
    }
}tr[maxn*5];
char str[maxn];
int Pow[maxn];
int suffix[30],prefix[30],odd[30],even[30];
int n,q;
node  ans;
void pushup(int st) {
    for(int i = 0;i<26;i++) tr[st].num[i] = tr[st<<1].num[i]+tr[st<<1|1].num[i];
}
void build(int L,int R,int st) {
    tr[st].Clear();
    if(L==R) {
        tr[st].num[str[L-1] - 'a']++;
        return ;
    }
    int mid = (L+R) >>1;
    build(L,mid,st<<1);
    build(mid+1,R,st<<1|1);
    pushup(st);
}
node Rotate(node a,int b) {
    node ans; ans.Clear();
    ans.lazy = a.lazy;
    for(int i = 0;i<26;i++) ans.num[(i+b)%26] = a.num[i];
    return ans;
}
void pushdown(int L,int R,int st) {
    if(L==R || tr[st].lazy == 0) return ;
    tr[st<<1].lazy = (tr[st<<1].lazy+tr[st].lazy)%26;
    tr[st<<1|1].lazy =(tr[st<<1|1].lazy+tr[st].lazy)%26;
    tr[st<<1] = Rotate(tr[st<<1],tr[st].lazy);
    tr[st<<1|1] = Rotate(tr[st<<1|1],tr[st].lazy);
    tr[st].lazy = 0;
}
void Update(int L,int R,int st,int l,int r,int tm) {
    if(l<=L && R<=r) {
        tr[st].lazy = (tr[st].lazy+tm)%26;
        tr[st] = Rotate(tr[st],tm);
        return ;
    }
    pushdown(L,R,st);
    int mid = (L+R) >>1;
    if(l<=mid) Update(L,mid,st<<1,l,r,tm);
    if(r> mid) Update(mid+1,R,st<<1|1,l,r,tm);
    pushup(st);
}
void Query(int L,int R,int st,int l,int r) {
    if(l<=L && R<=r) {
        for(int i = 0;i<26;i++) ans.num[i] = ans.num[i]+tr[st].num[i];
        return ;
    }
    pushdown(L,R,st);
    int mid = (L+R)>>1;
    if(l<=mid) Query(L,mid,st<<1,l,r);
    if(r>mid)  Query(mid+1,R,st<<1|1,l,r);
    pushup(st);
}
int Count() {
    int ant = 1;
    for(int i = 0;i<26;i++) {
        if(ans.num[i] ==0) {
            odd[i] = 0;
            even[i] = 1;
        }
        else {
            odd[i]  = Pow[ans.num[i]-1];
            even[i] = Pow[ans.num[i]-1];
        }
    }
    prefix[0] = even[0];
    for(int i = 1;i<26;i++) prefix[i] = (prefix[i-1]*1LL*even[i])%mod;
    suffix[25] = even[25];
    for(int i = 24;i>=0;i--) suffix[i] = (suffix[i+1]*1LL*even[i])%mod;
    ant = prefix[25];
    for(int i = 0;i<26;i++) {
        int cur = ((i == 0?1:prefix[i-1])*1LL*(i==25?1:suffix[i+1]))%mod;
        cur = (cur*1LL*odd[i])%mod;
        ant = (ant+cur)%mod;
    }
    return (ant-1+mod)%mod;
}
int main() {
    scanf("%d %d",&n,&q);
    int op,l,r,tm;
    Pow[0] = 1;
    for(int i = 1;i<maxn;i++) Pow[i] = (Pow[i-1]<<1)%mod;
    scanf("%s",str);
    build(1,n,1);
    while(q--) {
        scanf("%d %d %d",&op,&l,&r);
        if(op == 1) scanf("%d",&tm);
        l++,r++;
        if(op == 1) {
            Update(1,n,1,l,r,tm%26);
        }
        else {
            ans.Clear();
            Query(1,n,1,l,r);
            printf("%d\n",Count());
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/huayunhualuo/article/details/53668773
44
101