i,j 表示第i個節點擊了j這個權值的方案數。
顯然轉移方程為,fi
,j=π
v=so
n(i)
(∑k=
1j−k
fv,k
+∑k=
j+km
fv,k
) 接著上面的想法,
觀察轉移方程,發現,求和部分其實是兩段連續的,那麼將fi
求乙個字首和。觀察f
陣列,發現其實
f是對稱的,而且中間的一段是相同的,設深度為x,那麼前面就有(x
−1)k
個不同,然後中間有一段相同,後面又有(x
−1)k
個不同。
那麼就可以只求出前(x
−1)k
+1個,字首和就可以直接算出來(程式中我直接求出前10010個的值,沒有計算x)。
#include
#include
#include
#include
#include
#include
const
long
long maxlongint=2147483647;
const
long
long mo=1000000007;
const
long
long n=105;
using
namespace
std;
long
long f[n][n*n*2],_,n,m,k,next[n*2],last[n*2],to[n*2],tot,same[n],sum1[n][n*n],sum2[n][n*n];
long
long pos[n];
long
long max(long
long x,long
long y)
long
long min(long
long x,long
long y)
long
long bj(long
long x,long
long y)
long
long sum(int x,int y)
else
}long
long dg(long
long x,long
long fa)
}for(long
long i=1;i<=min(10010,m);i++) f[x][i]=1;
for(long
long i=last[x];i;i=next[i])
f[x][l]=(f[x][l]*t)%mo;}}
}if(10010
for(int i=1;i<=10010;i++)
}
}else
for(int i=1;i<=min(10010,m);i++)
sum1[x][i]=(sum1[x][i-1]+f[x][i])%mo;
for(int i=1;i<=min(10010,m);i++)
sum2[x][i]=(sum2[x][i-1]+f[x][pos[x]-i+1])%mo;
}int main()
dg(1,0);
printf("%lld\n",sum(1,m));}}
NOIP2016提高A組五校聯考1 道路規劃
我們考慮,當現在有乙個合法的集合時,如何往裡面增加乙個點,使這個集合仍然合法。假設現在有乙個合法的集合,那麼當我們加入乙個點,它的道路穿過來整個集合,那麼 然後搞一遍最長下降子串行就可以了。include include include include include const int maxlo...
NOIP2016提高A組五校聯考1 挖金礦
剛看到這題時,還在想怎麼貪心,然後很快的打完之後發現貪心是錯的。然後仔細的看了看範圍,哈哈,這不是二分嗎。二分出乙個mid,然後在所有行裡面用mid j 字首和然後找乙個最大值。最後把這些最大值加起來,判斷一下就好了。include include include include include i...
NOIP2016提高A組五校聯考1 挖金礦
答案,保留4位小數 4 3 4 3 3 5 1 6 2 6 1 3 2 9 4.4286 n m 100000 很簡單的一道題 設sum i j 表示第i列向下挖j行的字首和 假設第i列挖h i 行 設二分的答案是m,答案如果合法,那麼 n i 1s um i h i ni 1 h i m 移項 i...