牛客网暑期ACM多校训练营(第九场)+训练日记

今天的是欢乐场!大佬们看着我们受折磨而欢乐的欢乐场,,大佬说今天这场的题大多是经典题改编的,感觉很有意思,很多能看的题,,赶脚这套题可以好好研究研究,都比较经典。、

我们今天就A了一个题E,用的概率的知识点的思想。

E、Music Game

题意:n个位置,点或不点(1 or 0),每种情况没有连续x个位置都点了,即得价值X^m,求所有的期望

思路:概率上,其期望是概率*对应价值之和,本题可以得出对于所有情况,

对于每个区间【l,r】考虑,若区间[l,r]内均为1,且l-1,r+1为0,所有包含此区间情况的情况,都有通项((1-P(l-1))*P(l)*……*P(r)*(1-P(r+1)))*((r-l+1)^m),所以可提取出来,剩下的部分任意排列都符合,概率为1,所以整体的期望就是所有区间符合只此区间连续的期望和,,然后取逆元直接再输入P后直接处理就可,,

感想:简直要被这个题气死,做的时候预处理了很多,最后都没用上,,下面代码是删除无用的后,,再就是中间一直调不出来!,尝试输出又因为受逆元影响而无法辨别!!!然后因为自己粗心,将F【1】(表意:1^m,)写成了m~!!!!!真的是要剁手的节奏!!磨蹭了巨多时间!!!全因为这个1!!!这个粗心真的是要不得哇!!!!太坑了!

代码:

#include
using namespace std;
#define mod 1000000007
#define INV 570000004
long long sum[1005],n,m,F[1005],P[1005],ga[1005][1005];
long long AA(long long a,long long b)
{
    if(b==1) return a%mod;
    if(b%2) return (AA((a*a)%mod,b/2)%mod*a)%mod;
    else return AA((a*a)%mod,b/2)%mod;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    F[1]=1;
    for(int i=2;i<=n;i++)
    {
        F[i]=AA(i,m);
        F[i]%=mod;
    }
    for(int i=1;i<=n;i++)scanf("%lld",&P[i]),P[i]=(P[i]*INV)%mod,ga[i][i]=P[i];;
    long long r,ans=0,z;
    for(int l=2;l<=n;l++)
    {
        for(int i=1;i+l-1<=n;i++)
        {
            r=l+i-1;
            ga[i][r]=ga[i][r-1]*ga[r][r];
            ga[i][r]%=mod;
        }
    }
    for(int l=1;l<=n;l++)
    for(int i=1;i+l-1<=n;i++)
    {
        r=l+i-1;
        if(i-1>=1) z=(1-P[i-1]+mod)%mod;
        else z=1;
        if(r+1<=n) z*=(1-P[r+1]+mod)%mod;
        else z*=1;
        z%=mod;
        ans+=((((ga[i][r]*z)%mod)*F[l])%mod)%mod;
        ans%=mod;
    }
    printf("%lld\n",ans);
}

F、Typing practice

题意:给n个固定串,输入一系列操作,求每次后缀距离固定串的最小距离

思路:晚上看的直播,大佬说是数据出问题了,本来想将kmp,拓展kmp,AC自动机等全部卡掉的,但是数据没卡掉~,正解是trie图。。两眼一抹黑,,完全状况外,,但是比赛的时候这些方法都能过,,我们想的也是kmp,,但是没有调出来,,等着还是看看正解吧

代码:(PS:自己做的KMP的方法的,trie图的因为没学过,就看了看知识点,了解了一下,,也不做了,反正这个题的数据能过~trie图的就跟这个代码差个常数~)

#include
using namespace std;
int nextt[5][100005],ans[100005],len[5];
void getFail(char *P,int *f)//P模板串,f是next数组
{
    f[1]=f[0]=0;
    int m=strlen(P);
    for(int i=1,j;i

下面是AC自动机 的代码,是很优化的O(n*L+m)的复杂度,跟trie图的复杂度一样,偷的别人的~但是据说思路很好,但是我没有学过这些东西~看不太懂,暂时不看,以后如果还记得的话再看~

//AC自动机
//查询模式串出现次数
#include 
using namespace std;
queueque;
int ans[100003];
vectorg[100003];
struct Trie{
    int ch[100003][26];
    int fail[100003];
    int end[100003];
    int sz;
    int newnode(){
        for(int i=0;i<26;i++)ch[sz][i]=-1;
        end[sz]=0;
        return sz++;
    }
    void init(){
        memset(end,0,sizeof(end));
        sz=0;
        newnode();
    }
    int idx(char c){
        return c-'a';
    }
    void insert(char s[]){
        int len=strlen(s);
        int u=0;
        for(int i=0;iq;
        fail[0]=0;
        for(int i=0;i<26;i++){
            if(ch[0][i]==-1)ch[0][i]=0;
            else {
                fail[ch[0][i]]=0;
                q.push(ch[0][i]);
            }
        }
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(ch[u][i]==-1){
                    ch[u][i]=ch[fail[u]][i];
                }
                else {
                    fail[ch[u][i]]=ch[fail[u]][i];
                    q.push(ch[u][i]);
                }
            }
        }
        for(int i=0;i

H、Prefix Sum

题意:给定n,m,k,两种操作:

1 x y:a[0][x]+=y;

2 x : cout<

a[i][1] = a[i-1][1] and a[i][j] = a[i][j-1] + a[i-1][j] (j >= 2)

思路:据大佬讲,推出公式,,然后两种暴力结合,,构成m√n的复杂度。。

/*但是比赛的时候只推出公式。,,没想到为什么要化成更小的,还可能出现负数。。。有点惊呆,,明天在看,,*/

牛客网暑期ACM多校训练营(第九场)+训练日记_第1张图片

 

今天看了一下题解,真是优秀!!比赛时我们思路是对的,也一直在想办法维护组合数的和,当然无果~~完全没想到将组合数拆分出来维护、、然后代码也就粘别人的了,,树状数组不想敲了!

代码:

#include 
#include  
#include   
#include   
#include    
#include    
#include    
#include     
#include     
#include     
#include       
#include       
using namespace std;
typedef long long ll;
typedef pair P;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const double PI = acos(-1.0);
const double eps = 1e-10;
const int maxn = 1e5 + 7;
#define REP(i, j, k) for(int i = j;i < k; ++i)
#define PER(i, j, k) for(int i = k - 1;i >= j; --i)
int n, m, k;
ll tr[105][maxn], frac[maxn], i_frac[maxn], inv[105];
void add(int id, int x, ll val)
{
    while(x <= n)
    {
        tr[id][x] = (tr[id][x] + val) % mod;
        x += (x & -x);
    }
}
ll ask(int id, int x)
{
    ll res = 0;
    while(x > 0)
    {
        res = (res + tr[id][x]) % mod;
        x -= (x & -x);
    }
    return res;
}
void init()
{
    inv[1] = 1;
    REP(i, 2, 105) inv[i] = inv[mod % i] * (mod - mod / i) % mod;
}
int main()
{
#ifdef DEBUG
    freopen("input.txt", "r", stdin);
#endif // DEBUG
    scanf("%d %d %d", &n, &m, &k);
    k--;
    init();
    while(m--)
    {
        int op, x, y;
        scanf("%d %d", &op, &x);
        if(op == 0)
        {
            scanf("%d", &y);
            ll u = 1;
            REP(j, 0, k + 1)
            {
                add(j, x, u * y % mod);
                u = u * (k - x - j) % mod * inv[j + 1] % mod;
            }
        }
        else
        {
            ll ans = 0;
            ll u = 1;
            REP(j, 0, k + 1)
            {
                ans = (ans + u * ask(k - j, x) % mod) % mod;
                u = u * (x - j) % mod * inv[j + 1] % mod;
            }
            printf("%lld\n", (ans + mod) % mod);
        }
    }
    return 0;
}

 

你可能感兴趣的:(数学,假期集训心得与感想,数据结构,思维)