這么好的整數場,就終結了我連續莫名考好的記錄。
功德圓滿了。。。
還是炸了啊。而且炸的還挺厲害(自己又上不去自己粘的榜單啦)
說實在的這場考試做的非常差勁。雖說分數不算特別低但是表現是真的特別差。
T1看錯數據范圍,數組開小。
真的我以后只要不MLE還是多開一點數組吧不會鍋的。
而且好好看題好好看數據范圍!!!
T2亂搞+剪枝,數據水就過了。
關鍵是T3。如果T3打個特別簡單的暴力拿40就滾的話就是並列rank1了(雖說在文件評測下skyh多了5分會變成rank2)
但是因為正解很好想,想到了正解就沒有打暴力。
一個半小時,到死也沒調出來。
不要那么自信啊喂你那么菜老老實實打暴力啊先!!!
臨考前出這么多問題,也不知道我是要怎樣。
改。改就是了。
T1:組合
根據題目暗示可以抽象成圖論。
然后發現就是一個有/無向圖歐拉路板子。及時重置fir數組以及當前枚舉的邊i。(就是當前弧優化)
板子,看代碼就好了,這真的沒法說。
注意數據范圍以及n和m的含義不要看反,不要想當然以為nm同級。

1 #include<cstdio> 2 #define gg return puts("NO"),0 3 int t,n,m,cnt=1,fir[2000005],l[2000005],to[2000005],in[2000005],out[2000005],deg[2000005]; 4 int al[2000005],S,E,el[2000005],ans[2000005],tp; 5 void dfs(int p){ 6 al[p]=1; 7 for(int i=fir[p];i;i=l[i])if(!al[to[i]])dfs(to[i]); 8 } 9 void DFS(int p){ 10 for(int i=fir[p];i;)if(!el[i]){ 11 el[i]=1;fir[p]=l[i]; 12 if(t==1)el[i^1]=1; 13 DFS(to[i]); 14 ans[++tp]=i;i=fir[p]; 15 }else fir[p]=i=l[i]; 16 } 17 void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;in[b]++;out[a]++;} 18 int main(){ 19 freopen("merge.in","r",stdin); 20 freopen("merge.out","w",stdout); 21 scanf("%d%d%d",&t,&n,&m); 22 if(t==1){ 23 for(int i=1,x,y;i<=m;++i)scanf("%d%d",&x,&y),link(x,y),link(y,x); 24 for(int i=1;i<=n;++i)if(in[i]&1) 25 if(!S)S=i;else if(!E)E=i;else gg; 26 if(!S)for(int i=1;i<=n;++i)if(in[i])S=i; 27 dfs(S); 28 for(int i=1;i<=n;++i)if(!al[i]&&in[i])gg; 29 puts("YES"); 30 DFS(S); 31 while(tp)printf("%d ",(ans[tp]>>1)*(ans[tp]&1?-1:1)),tp--; 32 }else{ 33 for(int i=1,x,y;i<=m;++i)scanf("%d%d",&x,&y),link(x,y); 34 for(int i=1;i<=n;++i) 35 if(in[i]==out[i]+1){if(!E)E=i;else gg;} 36 else if(in[i]+1==out[i]){if(!S)S=i;else gg;} 37 else if(in[i]!=out[i])gg; 38 if(!S)for(int i=1;i<=n;++i)if(out[i])S=i; 39 dfs(S); 40 for(int i=1;i<=n;++i)if(!al[i]&&in[i])gg; 41 puts("YES"); 42 DFS(S); 43 while(tp)printf("%d ",ans[tp]-1),tp--; 44 } 45 }
T2:統計
觀察大樣例,發現到了后來操作約等於沒操作,只有很少的情況下會真正進行操作。
統計每個數后面有幾個比它小的,如果沒有那么就不操作。
這個統計可以在求逆序對時求出。

1 #include<cstdio> 2 #include<algorithm> 3 int a[200005],n,m,cnt[200005],t[200005],r[200005],rp[200005],tp;long long ans; 4 void add(int p,int w=1){for(;p<=n;p+=p&-p)t[p]+=w;} 5 int ask(int p,int a=0){for(;p;p^=p&-p)a+=t[p];return a;} 6 void cal(int p){tp=0; 7 for(int i=p;i<=n;++i)if(a[i]<=a[p])r[++tp]=a[i],rp[tp]=i; 8 std::sort(r+1,r+1+tp); 9 for(int i=1;i<=tp;++i)a[rp[i]]=r[i]; 10 for(int i=1;i<=n;++i)t[i]=0; 11 for(int i=n;i>=p;--i)ans-=cnt[i],ans+=(cnt[i]=ask(a[i]-1)),add(a[i]); 12 } 13 int main(){ 14 freopen("count.in","r",stdin); 15 freopen("count.out","w",stdout); 16 scanf("%d%d",&n,&m); 17 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 18 for(int i=n;i;--i)ans+=(cnt[i]=ask(a[i]-1)),add(a[i]); 19 printf("%lld ",ans); 20 while(m--){ 21 int x;scanf("%d",&x); 22 if(cnt[x])cal(x); 23 printf("%lld ",ans); 24 } 25 }
然而其實復雜度並不好,需要用線段樹或鏈表優化這個過程。
T3:點亮
首先聲明:題解傻逼了那個不是方案數那個是最優轉移值。。。
至今不知道考場上打的怎么錯了。
猜測隨機數據生成的樹與完全二叉樹相近,其實差不多,只不過2變成了e,log變成了ln。
考慮每一個點對最終答案的貢獻。
枚舉u,再枚舉所有點v,得到lca(u,v),根據u和lca(u,v)就可以知道貢獻是a[u][v]還是b[u][v]還是0。
所以預處理之后其實貢獻就與v無關了,只與u和lca有關。
因為隨機樹的深度期望為$ln \ n$(實際測試點里稍大,為14)
所以可以狀壓祖先鏈上所有的點,1表示這個點的子樹里點亮的點大於等於一半。
然后就可以根據祖先鏈上的情況判斷每個點在現在情況下的貢獻了。
然后狀態定義就是dp[i][j][k]表示以i為根的子樹里已經有j個點被點亮了,此時i的祖先鏈上的狀態為k。
然后就可以dp了。轉移就是經典的子樹歸並(所以可能需要滾動dp數組或者使用輔助數組,其實也可以不用)。
形式也很簡單,什么DP[p][S+s][j]=max(dp[p][S][j]+dp[son][s][k])什么的。
狀態數挺多的,得拿vector來resize存。
沒什么好說的。初值-inf。該預處理的預處理。
然后就是代碼細節問題。。。不是很好調,真的。。。
話說我感覺我這個$O(n^2)$遞推求出所有點對的lca還是挺帥的(僅適用於這種f[i]<i的)

1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 #define inf -66666666 6 int max(int a,int b){return a>b?a:b;} 7 int read(){ 8 register int nt=0,p=0;register char ch=getchar(); 9 while(ch<'0'||ch>'9')nt=ch=='-',ch=getchar(); 10 while(ch>='0'&&ch<='9')p=(p<<3)+(p<<1)+ch-'0',ch=getchar(); 11 return nt?-p:p; 12 } 13 int n,f[1005],a[1005][1005],b[1005][1005],lca[1005][1005],pre[2][1005][16]; 14 int fir[1005],l[1005],to[1005],cnt,sz[1005],Dep[1005],DP[1005][32767]; 15 vector<int>dp[1001][1001]; 16 void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;} 17 void DFS(int p){ 18 sz[p]=1;Dep[p]=Dep[f[p]]+1; 19 for(int i=fir[p];i;i=l[i])DFS(to[i]),sz[p]+=sz[to[i]]; 20 } 21 void dfs(int p){int dep=Dep[p],alsz=1,S=(1<<dep)-1; 22 for(int i=0;i<=sz[p];++i)dp[p][i].resize(S+1),dp[p][i].resize(S+1); 23 for(int i=0;i<=sz[p];++i)for(int j=0;j<1<<dep;++j)dp[p][i][j]=dp[p][i][j]=inf; 24 for(int j=0;j<1<<dep;++j){ 25 dp[p][0][j]=dp[p][1][j]=0; 26 for(int i=1;i<=15;++i)if(!(j&1<<i-1))dp[p][0][j]+=pre[0][p][i];else dp[p][1][j]+=pre[1][p][i]; 27 } 28 for(int i=fir[p];i;i=l[i]){int t=to[i]; 29 dfs(t); 30 for(int i=0;i<=alsz+sz[t];++i)for(int j=0;j<1<<dep;++j)DP[i][j]=inf; 31 for(int j=0;j<=sz[t];++j)for(int k=0;k<1<<dep;++k)for(int x=0;x<=alsz;++x) 32 DP[x+j][k]=max(DP[x+j][k],dp[p][x][k]+max(dp[t][j][k],dp[t][j][k+S+1])); 33 for(int i=0;i<=alsz+sz[t];++i)for(int j=0;j<1<<dep;++j)dp[p][i][j]=DP[i][j]; 34 alsz+=sz[t]; 35 } 36 for(int i=0;i<=sz[p];++i)for(int j=0;j<1<<dep;++j) 37 if(i<sz[p]-i&&j&1<<dep-1)dp[p][i][j]=inf; 38 else if(i>=sz[p]-i&&!(j&1<<dep-1))dp[p][i][j]=inf; 39 } 40 main(){ 41 freopen("light.in","r",stdin); 42 freopen("light.out","w",stdout); 43 n=read(); 44 for(int i=2;i<=n;++i)f[i]=read(),link(f[i],i); 45 for(int i=1;i<=n;++i){ 46 for(int j=1;j<i;++j)a[i][j]=read(),b[i][j]=read(); 47 for(int j=i+1;j<=n;++j)a[i][j]=read(),b[i][j]=read(); 48 } 49 for(int i=1;i<=n;++i)lca[i][i]=i; 50 for(int i=1;i<=n;++i)for(int j=1;j<i;++j)lca[i][j]=lca[j][i]=lca[f[i]][j]; 51 for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)lca[i][j]=lca[j][i]; 52 DFS(1); 53 for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)lca[i][j]=Dep[lca[i][j]]; 54 for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) 55 pre[0][i][lca[i][j]]+=a[i][j],pre[1][i][lca[i][j]]+=b[i][j]; 56 dfs(1); 57 int ans=inf; 58 for(int i=0;i<=sz[1];++i)ans=max(ans,max(dp[1][i][0],dp[1][i][1])); 59 printf("%d\n",ans); 60 }
注意那個pre數組的預處理,這個不能在里面枚舉祖先狀態時再枚舉每一個點暴力求,會退化成$O(n^3)$

1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 #define inf -66666666 6 int max(int a,int b){return a>b?a:b;} 7 int read(){ 8 register int nt=0,p=0;register char ch=getchar(); 9 while(ch<'0'||ch>'9')nt=ch=='-',ch=getchar(); 10 while(ch>='0'&&ch<='9')p=(p<<3)+(p<<1)+ch-'0',ch=getchar(); 11 return nt?-p:p; 12 } 13 int n,f[1005],a[1005][1005],b[1005][1005],lca[1005][1005]; 14 int fir[1005],l[1005],to[1005],cnt,sz[1005],Dep[1005],DP[1005][32767]; 15 vector<int>dp[1005][1005]; 16 void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;} 17 void DFS(int p){ 18 sz[p]=1;Dep[p]=Dep[f[p]]+1; 19 for(int i=fir[p];i;i=l[i])DFS(to[i]),sz[p]+=sz[to[i]]; 20 } 21 void dfs(int p){int dep=Dep[p],alsz=1,S=(1<<dep)-1; 22 for(int i=0;i<=sz[p];++i)dp[p][i].resize(S+1),dp[p][i].resize(S+1); 23 for(int i=0;i<=sz[p];++i)for(int j=0;j<1<<dep;++j)dp[p][i][j]=dp[p][i][j]=inf; 24 for(int j=0;j<1<<dep;++j){ 25 dp[p][0][j]=dp[p][1][j]=0; 26 for(int i=1;i<=n;++i)if(!(j&1<<lca[p][i]-1))dp[p][0][j]+=a[p][i]; 27 for(int i=1;i<=n;++i)if(j&1<<lca[p][i]-1)dp[p][1][j]+=b[p][i]; 28 } 29 for(int i=fir[p];i;i=l[i]){int t=to[i]; 30 dfs(t); 31 for(int i=0;i<=alsz+sz[t];++i)for(int j=0;j<1<<dep;++j)DP[i][j]=inf; 32 for(int x=0;x<=alsz;++x)for(int j=0;j<=sz[t];++j)for(int k=0;k<1<<dep;++k) 33 DP[x+j][k]=max(DP[x+j][k],dp[p][x][k]+max(dp[t][j][k],dp[t][j][k+S+1])); 34 for(int i=0;i<=alsz+sz[t];++i)for(int j=0;j<1<<dep;++j)dp[p][i][j]=DP[i][j]; 35 36 alsz+=sz[t]; 37 } 38 for(int i=0;i<=sz[p];++i)for(int j=0;j<1<<dep;++j) 39 if(i<sz[p]-i&&j&1<<dep-1)dp[p][i][j]=inf; 40 else if(i>=sz[p]-i&&!(j&1<<dep-1))dp[p][i][j]=inf; 41 } 42 int main(){ 43 freopen("light.in","r",stdin); 44 freopen("light.out","w",stdout); 45 n=read(); 46 for(int i=2;i<=n;++i)f[i]=read(),link(f[i],i); 47 for(int i=1;i<=n;++i){ 48 for(int j=1;j<i;++j)a[i][j]=read(),b[i][j]=read(); 49 for(int j=i+1;j<=n;++j)a[i][j]=read(),b[i][j]=read(); 50 } 51 for(int i=1;i<=n;++i)lca[i][i]=i; 52 for(int i=1;i<=n;++i)for(int j=1;j<i;++j)lca[i][j]=lca[j][i]=lca[f[i]][j]; 53 for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)lca[i][j]=lca[j][i]; 54 DFS(1); 55 for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)lca[i][j]=Dep[lca[i][j]]; 56 dfs(1); 57 int ans=inf; 58 for(int i=0;i<=sz[1];++i)ans=max(ans,max(dp[1][i][0],dp[1][i][1])); 59 printf("%d\n",ans); 60 }
%%%mikufun為什么調代碼那么快啊我調了半場考試加一個晚上才弄出來他半個晚上就過樣例直接秒切了
我好菜啊QAQ