不知道为啥当时咕了,然后咕了太久了,回来写反思的时候已经没有反思了。
反正我好菜啊,直接写题解吧。
T1:数据结构
大意:维护序列,单点修改,查询某个区间$[l,r]$的区间和的历史最小值。$n,q le 10^5$
$KD-tree$又日爆一切二维几何了。
牛神又日爆一切$KD-tree$题了。
矩形加,历史最小值,简单维护。$O(qsqrt{n})$
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define S 400005 4 #define ll long long 5 int cmp,op[S],x[S],y[S],n,m,a[S],qc,mxl[S],mnr[S],mxr[S],mnl[S]; 6 ll w[S],lz[S],mnlz[S],pre[S],mn[S]; 7 struct P{int l,r;}Q[S],T[S]; 8 ll cal(P x){return cmp?1000000000ll*x.l+x.r:1000000000ll*x.r+x.l;} 9 bool operator<(P x,P y){return cal(x)<cal(y);} 10 #define lc p<<1 11 #define rc lc|1 12 #define fa p>>1 13 void build(int p,int l,int r){ 14 if(l>r)return; 15 cmp^=1; int md=l+r>>1; 16 nth_element(Q+l,Q+md,Q+r+1); 17 T[p]=Q[md];mn[p]=w[p]=pre[mxr[p]=mnr[p]=T[p].r]-pre[(mnl[p]=mxl[p]=T[p].l)-1]; 18 build(lc,l,md-1);build(rc,md+1,r);cmp^=1; 19 mnr[fa]=min(mnr[fa],mnr[p]); mxl[fa]=max(mxl[fa],mxl[p]); 20 mxr[fa]=max(mxr[fa],mxr[p]); mnl[fa]=min(mnl[fa],mnl[p]); 21 } 22 void down(int p){ 23 if(!lz[p]&&!mnlz[p])return; 24 mn[lc]=min(mn[lc],w[lc]+mnlz[p]);mn[rc]=min(mn[rc],w[rc]+mnlz[p]); 25 w[lc]+=lz[p];w[rc]+=lz[p]; 26 mnlz[lc]=min(mnlz[lc],lz[lc]+mnlz[p]);mnlz[rc]=min(mnlz[rc],lz[rc]+mnlz[p]); 27 lz[lc]+=lz[p];lz[rc]+=lz[p]; 28 lz[p]=mnlz[p]=0; 29 } 30 void add(int L,int v,int p){ 31 if(mxr[p]<L||mnl[p]>L)return; 32 if(mxl[p]<=L&&mnr[p]>=L){lz[p]+=v;mnlz[p]=min(mnlz[p],lz[p]);w[p]+=v;mn[p]=min(mn[p],w[p]);return;} 33 if(T[p].l<=L&&T[p].r>=L)w[p]+=v,mn[p]=min(mn[p],w[p]); 34 down(p);add(L,v,lc);add(L,v,rc); 35 } 36 ll ask(int l,int r,int p){ 37 if(T[p].l==l&&T[p].r==r)return mn[p]; 38 cmp^=1;down(p);return ask(l,r,cal((P){l,r})<cal(T[p])?lc:rc); 39 } 40 int main(){ 41 scanf("%d%d",&n,&m); 42 for(int i=1;i<=n;++i)scanf("%d",&a[i]),pre[i]=pre[i-1]+a[i]; 43 for(int i=1;i<=m;++i){ 44 scanf("%d%d%d",&op[i],&x[i],&y[i]); 45 if(op[i]==2)Q[++qc]=(P){x[i],y[i]}; 46 } 47 build(1,1,qc); 48 for(int i=1;i<=m;++i) 49 if(op[i]==2)cmp=0,printf("%lld ",ask(x[i],y[i],1)); 50 else add(x[i],y[i]-a[x[i]],1),a[x[i]]=y[i]; 51 }
T2:B
大意:给定$01$串$S,T$,$S_i=[ai+b le c (mod n)]$。$S$是循环的。求$S$从第$p$位开始能和$T$匹配几位,或者单点修改$T$。$|T| le 10^5,others le 10^9$
如果$T_i=0$那么我们要查的就是$[0 le a(i+p)+b le c (mod n)]$,也就是说$[-ap le ai+b le c-ap (mod n)]$
所以只与$ai+b$有关在最开始的时候插入树状数组然后查询的时候只与$p$有关查询上述区间即可。
$T_i=1$同理。修改的话只要在树状数组里一删一加就行了。
1 #include<cstdio> 2 #define S 6000007 3 int n,m,b,c,q;char t[S];long long a; 4 struct hash_map{ 5 int fir[S],l[S],to[S],v[S],ec; 6 int&operator[](int x){ int r=x%S; 7 for(int i=fir[r];i;i=l[i])if(to[i]==x)return v[i]; 8 l[++ec]=fir[r];fir[r]=ec;to[ec]=x;return v[ec]; 9 } 10 }; 11 struct Fenwick_Tree{ 12 hash_map t; 13 void add(int p,int v=1){for(;p<=n;p+=p&-p)t[p]+=v;} 14 int ask(int p,int a=0){for(;p;p^=p&-p)a+=t[p];return a;} 15 int query(int l,int r){return l<=r?ask(r)-ask(l-1):ask(n)-(ask(l-1)-ask(r));} 16 }T[2]; 17 int mo(long long x){return (x%n+n)%n+1;} 18 int main(){ 19 scanf("%d%lld%d%d%d%s%d",&n,&a,&b,&c,&m,t,&q); 20 for(int i=0;i<m;++i)t[i]-=48,T[t[i]].add(mo(a*i)); 21 for(int _=1,o,p;_<=q;++_){ 22 scanf("%d%d",&o,&p); 23 if(o==2)T[t[p]].add(mo(a*p),-1),T[t[p]^=1].add(mo(a*p)); 24 else printf("%d ",T[0].query(mo(-a*p-b+c),mo(-a*p-b-1))+T[1].query(mo(-a*p-b),mo(-a*p-b+c-1))); 25 } 26 }
T3:C
大意:树,随机点出发,每个点有一个$01$状态,每一次会随机选择一个点,沿树边走到那个点并将其权值取反。所有点权值都相同时结束。求期望经过的总距离。$n le 10^5$
期望线性性,对每个点考虑贡献。
这是完全随机的游走,从每个点出发走到的点的距离期望是确定的可以直接换根$dp$得到。
然后所有点之间的区别就只剩下了:当前权值。状态的差异还有树上有几个权值为$1$的点。
根据这个设出$dp$。
这个东西,首先状态定义是:走到当前点,游戏未结束,此时当前点被经过的期望次数。要时刻注意你考虑的是一个点而不是一种权值的贡献
两个转移是出边和。前面的那个$frac{1}{n}$的常量是分别跟着后面系数为$frac{1}{n}$
分别讨论选中的是当前点,还是权值为$01$的点(第一个不包含于后两个)
所谓的边界情况是,$val_{0,0}=val_{0,1}=val_{n,0}=val{n,1}=0$。
然后$val_{n-1,0}$选自己会转移到$val_{n,1}$,不满足含义中“游戏仍在继续”的限制,所以没有$frac{1}{n}$的系数。$val_{1,1}$同理。
至此我们考虑了游戏仍在继续的情况(游戏不再继续你自然就不会再走)。没有考虑的就是随机出发所走的第一步,所以所有点的期望经过次数还要加$frac{1}{n}$
然后并不需要根据方程在$i=n-1$处列额外的方程,这东西有明显的对称性,所以显然有$val_{n-1,0}=val_{1,1},val_{n-1,1}=val_{1,0}$。
所以就解方程就行了。爆写式子有点细节。。。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int S=1e5+5,mod=1e9+7; 4 int fir[S],l[S],to[S],ec,n,d[S],sz[S],inv[S],v11,v10,cnt,ans;char s[S]; 5 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;} 6 int mo(int x){return x>=mod?x-mod:x;} 7 void dfs(int p){sz[p]=1;for(int i=fir[p],y;y=to[i];i=l[i])dfs(y),sz[p]+=sz[y],d[p]=mo(d[p]+mo(d[y]+sz[y]));} 8 void DFS(int p){for(int i=fir[p],y;y=to[i];i=l[i])d[y]=(0ll+d[p]-sz[y]+n-sz[y]+mod)%mod,DFS(y);} 9 int qp(int b,int t=mod-2,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;} 10 int gcd(int a,int b){return b?gcd(b,a%b):a;} 11 struct coef{ 12 int c0,c1,c; 13 coef operator+(coef x){return (coef){mo(c0+x.c0),mo(c1+x.c1),mo(c+x.c)};} 14 coef operator-(coef x){return (coef){mo(c0+mod-x.c0),mo(c1+mod-x.c1),mo(c+mod-x.c)};} 15 coef operator*(long long x){return (coef){c0*x%mod,c1*x%mod,c*x%mod};} 16 coef operator-(int x){return (coef){c0,c1,mo(c+mod-x)};} 17 int cal(){return (1ll*c0*v10+1ll*c1*v11+c)%mod;} 18 }c[S][2]; 19 int main(){ 20 scanf("%d%s",&n,s+1); inv[1]=1; 21 for(int i=2;i<=n;++i)inv[i]=mod-mod/i*1ll*inv[mod%i]%mod; 22 for(int i=2,a;i<=n;++i)scanf("%d",&a),link(a,i); 23 dfs(1);DFS(1); 24 c[1][0].c0=c[1][1].c1=1; 25 for(int i=1;i<n-1;++i) 26 c[i+1][1]=(c[i][1]*n-c[i-1][1]*(i-1)-c[i-1][0]-(i!=1))*inv[n-i], 27 c[i+1][0]=(c[i][0]*n-c[i-1][0]*i-c[i+1][1]-1)*inv[n-i-1]; 28 c[n][0]=c[1][1]-c[n-1][0]; 29 c[n][1]=c[1][0]-c[n-1][1]; 30 if(!c[n][1].c0)swap(c[n][0],c[n][1]);else c[n][0]=c[n][0]*qp(c[n][0].c0)*c[n][1].c0-c[n][1]; 31 v11=mod-1ll*qp(c[n][0].c1)*c[n][0].c%mod,v10=mo(mod+mod-1ll*v11*c[n][1].c1%mod-c[n][1].c)*1ll*qp(c[n][1].c0)%mod,cnt=0,ans=0; 32 for(int i=1;i<=n;++i)cnt+=s[i]-48; 33 for(int i=1;i<=n;++i)ans=(ans+(c[cnt][s[i]-48].cal()+inv[n])*1ll*d[i])%mod; 34 printf("%lld ",ans*1ll*qp(n)%mod); 35 }