日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2.10模拟总结

發布時間:2023/12/3 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2.10模拟总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 題目解析
    • 隨機減法(calculate)
    • 大圖書館(bibliotheca)
    • 子串選取 (substr)
  • 代碼
    • T1
    • T2
    • T3
  • 總結

前言

200pts
40+100+60
rnk3
拿到牌勒嘿嘿嘿(腦補流口水黃豆)

T3兩個log想在ybt的機子上過5e5確實是奢望了。
把串反過來改一改dp定義看出題解的那個性質就可以拿掉那個log,有些可惜。
但畢竟沒有掛分,還是不錯的=v=

題目解析

隨機減法(calculate)

乍一看這個題就感覺在 OI-wiki 上見過。
但是就記得在OIwiki上有了,屬于那個章節,怎么做統統不記得…
于是就只配打暴力了…
其實也看出了卷積,但那個東西需要再變成封閉形式化一下,必然還是脫離不了 O(k)O(k)O(k) 的復雜度。
而且看到 1e9+71e9+71e9+7 這種模數本能的覺得不是多項式…
而且為啥我的dp轉移和題解又不一樣,難看的很難化了…

題目的貢獻其實也就是 ∏ai\prod a_iai?變化量
即:
∏ai?∏ai′\prod a_i-\prod a_i'ai??ai?
前面已知,考慮如何算后面的貢獻。

設每個數的刪除次數為 d1...nd_{1...n}d1...n?,則有:
ans=∑∑di=kk!∏(ai?di)∏di!ans=\sum_{\sum d_i=k}\frac{k!\prod(a_i-d_i)}{\prod d_i!}ans=di?=k?di?!k!(ai??di?)?
=k!∑∑di=k∏(ai?di)∏di!=k!\sum_{\sum d_i=k}\frac{\prod(a_i-d_i)}{\prod d_i!}=k!di?=k?di?!(ai??di?)?
設后面這個東西的生成函數為 GGG,那么它其實就是 nnn 個形如 Fp=∑i=0∞(ap?i)xii!F_p=\sum_{i=0}^{\infty}\dfrac{(a_p-i)x^i}{i!}Fp?=i=0?i!(ap??i)xi? 的EGF卷起來。
然后把這個 FFF 化一下:
Fp=∑i=0∞(ap?i)xii!F_p=\sum_{i=0}^{\infty}\dfrac{(a_p-i)x^i}{i!}Fp?=i=0?i!(ap??i)xi?
=ap?∑i=0∞xii!?∑i=1∞xi(i?1)!=a_p\cdot\sum_{i=0}^{\infty}\dfrac{x^i}{i!}-\sum_{i=1}^{\infty}\dfrac{x^i}{(i-1)!}=ap??i=0?i!xi??i=1?(i?1)!xi?
=ap?∑i=0∞xii!?∑i=0∞xi+1i!=a_p\cdot\sum_{i=0}^{\infty}\dfrac{x^i}{i!}-\sum_{i=0}^{\infty}\dfrac{x^{i+1}}{i!}=ap??i=0?i!xi??i=0?i!xi+1?
=(ap?x)?∑i=0∞xii!=(a_p-x)\cdot\sum_{i=0}^{\infty}\dfrac{x^i}{i!}=(ap??x)?i=0?i!xi?
=(ap?x)?ex=(a_p-x)\cdot e^x=(ap??x)?ex
那么就有:
G=∏p=1nFpG=\prod_{p=1}^nF_pG=p=1n?Fp?
G=∏p=1n((ap?x)ex)G=\prod_{p=1}^n((a_p-x)e^x)G=p=1n?((ap??x)ex)
G=(∏p=1n(ap?x))enxG=(\prod_{p=1}^n(a_p-x))e^{nx}G=(p=1n?(ap??x))enx
前面的 ∏p=1n(ap?x)\prod_{p=1}^n(a_p-x)p=1n?(ap??x) 可以暴力背包求解,設得到的函數為 fff
那么就有:
G=(∑i=0∞fixi)×(∑i=0∞(nx)ii!)G=(\sum_{i=0}^{\infty}f_ix^i)\times (\sum_{i=0}^{\infty}\frac{(nx)^i}{i!})G=(i=0?fi?xi)×(i=0?i!(nx)i?)
那么最終得到的期望就是 GGG 的第 kkk 項乘上 k!k!k! 再除以 nkn^knk,即:
E=∑i=0fi?ki ̄niE=\sum_{i=0}\frac{f_i\cdot k^{\underline i}}{n^i}E=i=0?nifi??ki??
答案就是:
∏ai?E\prod a_i-Eai??E
總復雜度 O(n2)O(n^2)O(n2)

大圖書館(bibliotheca)

被A穿了的一道題…
15提交14AC一個96就離譜…
說實話我感覺這道題沒有那么簡單啊…
網絡流顯而易見,建圖方法五花八門。
我的做法是轉化為k重線段覆蓋集問題然后直接做。
題解的做法把“不買書” 轉化為一次買書和一次“賣書”,然后回溯連邊,也是挺不錯的。

子串選取 (substr)

挺可惜的一道題,差一點點。
感覺很經典的一道字符串題。
似乎必然是要SAM的,所以直接往那邊想了。
然后又無腦的上了線段樹合并 endpos 集合的套路。
然后找找性質二分搞吧搞吧就兩個log了。
但是5e5兩只log是過不去的…

先把串反過來,設計 dpidp_idpi? 表示以 iii 結尾的最大答案。
然后就有一個非常優秀的性質:fi≤fi?1+1f_i\le f_{i-1}+1fi?fi?1?+1
較為顯然,把 fif_ifi? 的一種方案每個串刪去結尾,就能得到答案為 fi?1f_{i}-1fi??1 且以 i?1i-1i?1 結尾的方案。
有了這個之后每次就不用二分 dp 值了,直接從上一個繼承來然后不斷暴力check,不合法就減減即可,有點類似于后綴數組求 heightheightheight
這樣就把第二只 log 拿掉了,復雜度變為單 log,可以通過。

代碼

T1

#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } const int N=5e3+100; const int B=150; const int inf=2e9; const int mod=1e9+7;int n,m;int a[N]; ll f[2][N],c[5]; inline ll ksm(ll x,ll k){ll res(1);while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res; }signed main(){freopen("calculate.in","r",stdin);freopen("calculate.out","w",stdout);//printf("%d\n",sizeof(t)/1024/1024);n=read();m=read();ll ans=1;for(int i=1;i<=n;i++) a[i]=read(),ans=ans*a[i]%mod;int now=1,pre=0;f[now][0]=1;for(int k=1;k<=n;k++){c[0]=a[k];c[1]=mod-1;swap(pre,now);memset(f[now],0,sizeof(f[now]));for(int i=0;i<=(k-1);i++){for(int j=0;j<=1;j++){f[now][i+j]=(f[now][i+j]+f[pre][i]*c[j])%mod;}}}ll E(0),bas=1,mi=1,ni=ksm(n,mod-2);for(int i=0;i<=n;i++){if(i) bas=bas*(m-i+1)%mod,mi=mi*ni%mod;E=(E+f[now][i]*bas%mod*mi)%mod;}printf("%lld\n",(ans+mod-E)%mod);return 0; } /* 12 abcdbabcabba */

T2

#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } const int N=4e3+100; const int B=150; const int inf=2e9; const int mod=998244353;int n,m; int ww=1e6+1;int s,t,tot; struct node{int to,nxt,cap,w; }p[N*N]; int fi[N],cur[N],cnt; inline void addline(int x,int y,int c,int w){p[++cnt]=(node){y,fi[x],c,w};fi[x]=cnt;return; } inline void add(int x,int y,int c,int w){addline(x,y,c,w);addline(y,x,0,-w);//printf(" %d->%d cap=%d w=%d\n",x,y,c,w);return; } int dis[N]; bool vis[N]; queue<int>q; bool spfa(){fill(dis,dis+1+tot,inf);dis[s]=0;q.push(s);vis[s]=1;while(!q.empty()){int now=q.front();q.pop();vis[now]=0;for(int i=cur[now]=fi[now];~i;i=p[i].nxt){int to=p[i].to;if(!p[i].cap||dis[to]<=dis[now]+p[i].w) continue;dis[to]=dis[now]+p[i].w;if(!vis[to]){vis[to]=1;q.push(to);}}}return dis[t]<inf; } int flow,cost; int dfs(int x,int lim){if(!lim||x==t){cost+=lim*dis[t];return lim;}if(vis[x]) return 0;vis[x]=1;int res(0);for(int &i=cur[x];~i;i=p[i].nxt){int to=p[i].to;if(dis[to]!=dis[x]+p[i].w) continue;int add=dfs(to,min(lim,p[i].cap));res+=add;lim-=add;p[i].cap-=add;p[i^1].cap+=add;if(!lim) break;}if(!res) dis[x]=-1;vis[x]=0;return res; } void dinic(){flow=cost=0;int tmp(0);while(spfa()){while((tmp=dfs(s,inf))) flow+=tmp;}return; }struct line{int l,r,val; }l[N]; int pre[N],lst[N]; int a[N],c[N],ans;signed main(){freopen("bibliotheca.in","r",stdin);freopen("bibliotheca.out","w",stdout);//printf("%d\n",sizeof(p)/1024/1024);memset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();for(int i=1;i<=n;i++) a[i]=read();for(int i=1;i<=n;i++) c[i]=read();for(int i=1;i<=n;i++){pre[i]=lst[a[i]];ans+=c[a[i]];lst[a[i]]=i;}for(int i=1;i<=n;i++){int x=lst[i];while(pre[x]){l[++tot]=(line){pre[x],x,c[i]};x=pre[x];}}for(int i=1;i<=n;i++) l[++tot]=(line){i,i,ww};ans+=n*ww;int num=tot;tot<<=1;s=++tot;t=++tot;int o=++tot;add(s,o,m,0);for(int i=1;i<=num;i++){//printf("i=%d (%d %d)\n",i,l[i].l,l[i].r);add(o,i,1,0);add(i,i+num,1,-l[i].val);add(i+num,t,1,0);for(int j=1;j<=num;j++){if(i==j) continue;if(l[j].l>=l[i].r) add(i+num,j,1,0);}}dinic();printf("%d\n",ans+cost);return 0; } /* 9 2 2 1 2 1 2 3 1 2 3 1 2 3 0 0 0 0 0 0 */

T3

#include<bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define debug(...) fprintf(stderr,__VA_ARGS__) #define ok debug("OK\n") inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f; } const int N=1e6+100; const int B=150; const int inf=2e9; const int mod=998244353;int n,m;struct tree{int ls,rs,sum,suf; }; struct Segment_Tree{#define mid ((l+r)>>1)tree tr[N*30];int tot;inline int copy(int x){tr[++tot]=tr[x];return tot;}inline void pushup(int k){tr[k].sum=tr[tr[k].ls].sum+tr[tr[k].rs].sum;tr[k].suf=max(tr[tr[k].ls].suf,tr[tr[k].rs].suf);return;}void upd(int &k,int l,int r,int p,int w){if(!k) k=copy(0);if(l==r){tr[k].sum+=w;tr[k].suf=l;return;}if(p<=mid) upd(tr[k].ls,l,mid,p,w);else upd(tr[k].rs,mid+1,r,p,w);pushup(k);}int merge(int x,int y,int l,int r){if(!x||!y) return x|y;int now=copy(x);tr[now].ls=merge(tr[now].ls,tr[y].ls,l,mid);tr[now].rs=merge(tr[now].rs,tr[y].rs,mid+1,r);pushup(now);return now;}int findsuf(int k,int l,int r,int x,int y){if(x>y) return 0;if(!k) return 0;if(x<=l&&r<=y) return tr[k].suf;int res=0;if(y>mid) res=max(res,findsuf(tr[k].rs,mid+1,r,x,y));if(res) return res;if(x<=mid) res=max(res,findsuf(tr[k].ls,l,mid,x,y));return res;}#undef mid }t; int rt[N];int fa[N],len[N],tr[N][26],tot=1,lst=1,state[N]; inline void ins(int c,int pos){c-='a';int cur=++tot,p=lst;lst=tot;state[pos]=cur;t.upd(rt[cur],1,n,pos,1);len[cur]=len[p]+1;for(;p&&!tr[p][c];p=fa[p]) tr[p][c]=cur;if(!tr[p][c]) fa[cur]=1;else{int q=tr[p][c];if(len[q]==len[p]+1) fa[cur]=q;else{int nq=++tot;len[nq]=len[p]+1;fa[nq]=fa[q];for(int i=0;i<26;i++) tr[nq][i]=tr[q][i];fa[cur]=fa[q]=nq;for(;p&&tr[p][c]==q;p=fa[p]) tr[p][c]=nq;}}return; } vector<int>v[N]; int pl[N][20]; void dfs(int x){pl[x][0]=fa[x];//printf("i=%d k=0 pl=%d\n",i,pl[i][0]);for(int k=1;pl[x][k-1];k++){pl[x][k]=pl[pl[x][k-1]][k-1];//printf("i=%d k=%d mid=%d pl=%d\n",i,k,pl[i][k-1],pl[i][k]);}for(int to:v[x]){dfs(to);rt[x]=t.merge(rt[x],rt[to],1,n);}return; } void build(){for(int i=2;i<=tot;i++) v[fa[i]].push_back(i);dfs(1);return; } inline int jump(int x,int l){//printf(" jump: x=%d L=%d\n",x,l);for(int k=19;k>=0;k--){//if(pl[x][k]) printf(" k=%d pl=%d len=%d\n",k,pl[x][k],len[pl[x][k]]);if(len[pl[x][k]]>=l) x=pl[x][k];}return x; }char s[N],ss[N]; int dp[N],mx,ans; bool check(int x,int L){//printf("check: x=%d L=%d\n",x,L);int s=jump(state[x],L-1);int pl=t.findsuf(rt[s],1,n,1,x-L);//printf(" cutpre: s=%d (%d %d) pl=%d state=%d\n",s,1,x-L,pl,state[x]);if(dp[pl]>=L-1) return true; if(x>1){s=jump(state[x-1],L-1);pl=t.findsuf(rt[s],1,n,1,x-L);//printf(" cutsuf: s=%d (%d %d) pl=%d state=%d\n",s,1,x-L,pl,state[x-1]);if(dp[pl]>=L-1) return true; }return false; } void DP(){for(int i=1;i<=n;i++){dp[i]=dp[i-1]+1;while(dp[i]>1&&!check(i,dp[i])) --dp[i];ans=max(ans,dp[i]);//printf("i=%d dp=%d\n\n",i,dp[i]);}return; } signed main(){freopen("substr.in","r",stdin);freopen("substr.out","w",stdout);//printf("%d\n",sizeof(t)/1024/1024);n=read();scanf(" %s",ss+1);for(int i=1;i<=n;i++) s[i]=ss[n-i+1];//printf("%s\n",s+1);for(int i=1;i<=n;i++) ins(s[i],i);//for(int i=1;i<=tot;i++) printf("i=%d fa=%d len=%d\n",i,fa[i],len[i]);build();DP();printf("%d\n",ans);return 0; } /* 12 abcdbabcabba */

總結

感覺最近不再像一開始那樣瘋狂掛分了。
明天就要上學校了,加油!awa

總結

以上是生活随笔為你收集整理的2.10模拟总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。