化一下試子就ok
#include#includeinline long long read()
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}long long n;
long long a[100007];
long long sum[100007];
long long sum2[100007];
int main()
return 0;
}
設\(g(n)\)為長為n的環的方案數
設\(f(n)\)為長為n的序列方案書
容易得到遞推式
\(g(n) = f(n) - g(n - 1)\)
由於\(a_1>a_n\)的時候不好處理,我們直接把環轉一下,讓1位置為最小值
對於\(f(n)\)可以容斥求得
\[f_i = \sum_j f_j \times \min(a[j+1... i]) \times (-1)^ \\
f_i = (-1)^ \sum_j\min(a[j+1...i]) \times f_j \times (-1)^\]
考慮 i 轉移到 i+1 時候:
\[\min(a[j+1...i]) \to \min(a[j+1...i+1]
\]單調棧為維護一下就好了,單調棧維護
#include#include#include#define pc putchar
#define gc getchar
inline int read()
#define ll long long
const int mod = 1000000007;
void print(ll x)
if(x >= 10)print(x / 10);
pc(x % 10 + '0');
} #define inf 0x3f3f3f3f3f3f3f3fll
const int maxn = 4000007;
ll a[maxn],b[maxn];
int n;
inline void mo(ll &x,ll y)
ll st[maxn][3];
int main()
int mn = 1;
for(int i = 2;i <= n;++ i)
for(int i = 1;i <= n;++ i) b[i] = a[(mn + i - 2) % n + 1];
int tp = 1;
memset(a,0,sizeof a);
ll ans = 0;
a[0] = n & 1 ? -1 : 1;
st[1][0] = inf,
st[1][1] = a[0];
for(int i = 1;i <= n;++ i)
mo(ans,n & 1? - b[1]:b[1]);
print(ans);
}
nowcoder提高組四 滅蟲
題意 3000個在數軸上的點,對於每個點可以選擇這個點向左延伸li長度的線段,或者這個點向右延伸ri長度的線段,問選擇的方法使得最終覆蓋的數軸長度最長,輸入均在int以內。乙個非常巧妙的dp題。首先這一類題目有重複的線段長度統計 或者是樹上的可以相交的路徑方案統計 或者其他內容有乙個比較自然的做法 ...
Nowcoder 提高組練習賽 R7
nowcoder 提高組練習賽 r7 中間空了兩場,因為實在是太難了.第五場的第二題好像還比較可做,是乙個最小生成樹的結論題,注意到 2 i 可以認為是二進位制下的數,即使把比它小的所有 2 x 全加起來也還是比他小,這一點做題的時候可以用一下.第六場的第一題是一道很奇怪的題目,給圖上的每條邊賦乙個...
NOI Online2 提高組 子串行問題 題解
題目傳送門 題目大意 給出乙個序列,求 1 i j n f i,j 2 sum f i,j 2 1 i j n f i,j 2 其中 f i j f i,j f i,j 表示 i ii j jj 有多少個不同的元素。思路挺簡單的,先考慮固定 l 1 l 1l 1,然後求出所有 f 1 r f 1,r...