[考試反思]0525省選模擬105:擱淺

不知道爲啥當時咕了,然後咕了太久了,回來寫反思的時候已經沒有反思了。

反正我好菜啊,直接寫題解吧。

 

T1:數據結構

大意:維護序列,單點修改,查詢某個區間$[l,r]$的區間和的歷史最小值。$n,q \le 10^5$

$KD-tree$又日爆一切二維幾何了。

牛神又日爆一切$KD-tree$題了。

矩形加,歷史最小值,簡單維護。$O(q\sqrt{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\n",ask(x[i],y[i],1));
50         else add(x[i],y[i]-a[x[i]],1),a[x[i]]=y[i];
51 }
View Code

 

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\n",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 }
View Code

 

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\n",ans*1ll*qp(n)%mod);
35 }
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章