【loli的胡策】测试4.16(线段树+概率期望dp)

标签: 线段树 概率期望dp
13人阅读 评论(0) 收藏 举报
分类:

T1

这里写图片描述

题解

仔细分析了题目发现并不是后缀家族的(松口气

然后随便想了一个简单的思路,每次查询的时候遇到’)’就用链表遍历’(‘,然后遍历之间的’w’,至于’0’我们用一个树状数组查看w左边的‘0’个数和右边的‘0’个数乘积就是ans,然而这样的时间复杂度是很不稳妥的O(n2logn),60pts

然而这种区间修改单点修改我应该想到的———线段树
线段树维护区间内有多少(0w0)
区间内出现的答案分两种:
不跨越中线的:左右子区间答案相加
跨越中线的:分4种:
(0w0在左侧,)在右侧
(0w在左侧,0)在右侧
(0在左侧,w0)在右侧
(在左侧,0w0)在右侧
那么我们就需要维护每个区间内(,(0,(0w,(0w0,0w0),w0),0),)
那我们设f[i][j]表示颜文字i~j这一段在这个区间内出现的次数,那么f[i][j]=fl[i][j]+fr[i][j]+k=ij1(fl[i][k]+fr[k+1][j])
那么时间复杂度为O(nlogn),还有合并时候的常数,不是很大

代码

60pts

#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
const LL mod=4294967296LL;
const int N=50005;
int n,num[N],m,nxtz[N],nxtw[N];char st[N];
void add(int loc,int vv){for (int i=loc;i<=n;i+=i&(-i)) num[i]+=vv;}
int qurry(int loc)
{
    int ans=0;
    for (int i=loc;i>=1;i-=i&(-i)) ans+=num[i];
    return ans;
}
int main()
{
    freopen("0w0.in","r",stdin);
    freopen("0w0.out","w",stdout);
    scanf("%d%d",&n,&m);
    scanf("%s",st+1);
    while (m--)
    {
        char w[5],c[5];int x,y;
        scanf("%s",w);scanf("%d",&x);
        if (w[0]=='B')
        {
            scanf("%d",&y);scanf("%s",c);
            for (int i=x;i<=y;i++) st[i]=c[0];
        }else if (w[0]=='A') 
        {
            scanf("%s",c);
            st[x]=c[0]; 
        }else
        {
            scanf("%d",&y);LL ans=0;
            for (int i=1;i<=n;i++) num[i]=0;
            int pointz=0,pointw=0;
            for (int i=x;i<=y;i++) 
            {
                if (st[i]==')')
                  for (int j=pointz;j;j=nxtz[j])
                    for (int k=pointw;k;k=nxtw[k])
                      if (k<j) break;
                      else ans=(ans+(LL)(qurry(k)-qurry(j))*(LL)(qurry(i)-qurry(k))%mod)%mod;       
                if (st[i]=='(') nxtz[i]=pointz,pointz=i;
                if (st[i]=='0') add(i,1);
                if (st[i]=='w') nxtw[i]=pointw,pointw=i;
            }
            printf("%lld\n",ans);
        }
    }
}

100pts
这个模数直接用int自然溢出就行,最后%u

#include <cstdio>
#include <cstring>
#include <iostream>
#define LL long long
using namespace std;
const LL mod=4294967296LL;
const int N=50005;
int n,m,f[N*4][6][6],ans,tmpans;char st[N],delta[N*4];
//( 0 w 0 )
//1 2 3 4 5
int pd(char v)
{
    if (v=='(') return 1;
    if (v=='0') return 2;
    if (v=='w') return 3;
    if (v==')') return 5;
    return 0;
}
void updata(int now,int l,int r)
{
    for (int i=1;i<=5;i++)
      for (int j=i;j<=5;j++)
      {
        f[now][i][j]=f[l][i][j]+f[r][i][j];
        for (int k=i;k<j;k++) f[now][i][j]+=f[l][i][k]*f[r][k+1][j];
      }
}
void pushdown(int now,int l,int r,int mid)
{
    if (delta[now])
    {
        memset(f[now<<1],0,sizeof(f[now<<1]));
        memset(f[now<<1|1],0,sizeof(f[now<<1|1]));
        int sb=pd(delta[now]);
        if (sb==2)
        {
            f[now<<1][2][2]=f[now<<1][4][4]=mid-l+1;
            f[now<<1|1][2][2]=f[now<<1|1][4][4]=r-mid;
        }else 
        {
            f[now<<1][sb][sb]=mid-l+1;
            f[now<<1|1][sb][sb]=r-mid;
        }
        delta[now<<1]=delta[now];
        delta[now<<1|1]=delta[now];
        delta[now]=0;
    }
}
void build(int now,int l,int r)
{
    if (l==r)
    {
        tmpans=max(now,tmpans);
        if (st[l]=='(') f[now][1][1]=1;
        else if (st[l]=='0') f[now][2][2]=f[now][4][4]=1;
        else if (st[l]=='w') f[now][3][3]=1;
        else if (st[l]==')') f[now][5][5]=1;
        return;
    }
    int mid=(l+r)>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    updata(now,now<<1,now<<1|1);
}
void qurry(int now,int l,int r,int lrange,int rrange)
{
    if (lrange<=l && rrange>=r)
    {
        updata(ans,tmpans,now);
        memcpy(f[tmpans],f[ans],sizeof(f[tmpans]));
        return;
    }
    int mid=(l+r)>>1;pushdown(now,l,r,mid);
    if (lrange<=mid) qurry(now<<1,l,mid,lrange,rrange);
    if (rrange>mid) qurry(now<<1|1,mid+1,r,lrange,rrange);
    updata(now,now<<1,now<<1|1);
}
void change(int now,int l,int r,int lrange,int rrange,char v)
{
    if (lrange<=l && rrange>=r)
    {
        delta[now]=v;
        memset(f[now],0,sizeof(f[now]));
        int sb=pd(v); 
        if (sb==2) f[now][2][2]=f[now][4][4]=r-l+1;
        else f[now][sb][sb]=r-l+1;
        return;
    }
    int mid=(l+r)>>1;pushdown(now,l,r,mid);
    if (lrange<=mid) change(now<<1,l,mid,lrange,rrange,v);
    if (rrange>mid) change(now<<1|1,mid+1,r,lrange,rrange,v);
    updata(now,now<<1,now<<1|1);
}
int main()
{
    freopen("0w0.in","r",stdin);
    freopen("0w0.out","w",stdout);
    scanf("%d%d",&n,&m);
    scanf("%s",st+1);
    build(1,1,n);
    ans=0;tmpans++;
    while (m--)
    {
        char w[5],c[5];int x,y;
        scanf("%s",w);scanf("%d",&x);
        if (w[0]=='B')
        {
            scanf("%d",&y);scanf("%s",c);
            change(1,1,n,x,y,c[0]);
        }else if (w[0]=='A') scanf("%s",c),change(1,1,n,x,x,c[0]);
        else
        {
            scanf("%d",&y);
            memset(f[ans],0,sizeof(f[ans]));
            memset(f[tmpans],0,sizeof(f[tmpans]));
            qurry(1,1,n,x,y);
            printf("%u\n",f[ans][1][5]);
        }
    }
}

T2

这里写图片描述
这里写图片描述
这里写图片描述

题解

这里写图片描述

查看评论

【loli的胡策】NOIP训练7.18(乱搞+背包dp+并查集分治)

今天的分数很可观哦
  • Blue_CuSO4
  • Blue_CuSO4
  • 2017-07-18 14:46:10
  • 220

【loli的胡策】测试3.28 T1(博弈)

题目: 题解: 一看到是博弈就吓住了,害怕是什么SG乱搞。然而这道题目并不要什么SG函数 我们发现所有的状态只有2n个点,即Alice/Bob先手,棋子在第i个位置。那么显然棋子在1的两...
  • Blue_CuSO4
  • Blue_CuSO4
  • 2018-03-28 18:43:20
  • 11

【loli的胡策】测试3.26 (贪心+hash)

T1 : 题解: 今天的T1犯了经验主义的错误,一眼二分之后死在了寻找答案的路上。 其实并不需要二分,考虑每次删除出现次数最多的项目,每次更新最小值获得答案,时间复杂度O(nm)O(n...
  • Blue_CuSO4
  • Blue_CuSO4
  • 2018-03-26 15:24:04
  • 18

【loli的胡策】测试4.20(主席树+凸包)

T1: n个数,m个询问,强制在线,每次给出l,r,求区间mex值 a[i]&amp;lt;=1e9,n,m&amp;lt;=200000 题解: 我为什么这么ZZ 这样的思路以前应该见...
  • Blue_CuSO4
  • Blue_CuSO4
  • 2018-04-20 16:25:48
  • 16

期望&概率dp总结

总算刷完kuangbin期望&概率专题了,下面总结一下心得和题解! 心得:期望dp通常逆推,即从结果推向初始状态,也可以用记忆化搜索进行dp;通常对于某个状态下的期望值E,E=Σp1*(E1+X1...
  • qq_31759205
  • qq_31759205
  • 2017-01-25 16:34:08
  • 2339

[学习笔记]概率与期望dp做题总结

之前做的一些就不记录了,只记录现在开始做的一些题。 T0. 入门题 给一个有向无环图,每次等概率走某一条边,求从1走到n的边权和的期望。 做法1,直接设dp[x]表示答案,转移显然。 做法2,...
  • Mys_C_K
  • Mys_C_K
  • 2017-10-25 14:25:37
  • 258

弱省胡策系列简要题解

现在不是非常爽,感觉智商掉没了,就整理一下最近弱省胡策的题目吧. 其实题目质量还是很高的. 如果实在看不懂官方题解,说不定这里bb的能给您一些帮助呢?【弱省胡策】Round #0 A20%数据,O...
  • wyfcyx_forever
  • wyfcyx_forever
  • 2015-06-18 20:19:46
  • 1377

【loli的胡策】训练1.14(组合数学+概率期望+乱搞)

T1 n,k,m 题解: 这个题一看没有什么思路,其实可以想象成一个递推关系,仔细来说,对于题目描述的集合,第m位上的数字范围是[m,n-(k-m)],在枚举集合的时候,只要保证后面的元...
  • Blue_CuSO4
  • Blue_CuSO4
  • 2018-01-14 21:56:36
  • 171

线段树模板(来自胡浩大牛)

http://www.notonlysuccess.com/(今天看二叉树,想回来看看,发现大牛博客进不去。。。) 如果要学,就要好好学。我copy的,如有错,请看http://www.cnblog...
  • Chrome_matrix_68
  • Chrome_matrix_68
  • 2016-08-08 17:54:25
  • 1471
    个人资料
    持之以恒
    等级:
    访问量: 7万+
    积分: 7539
    排名: 3627
    最新评论