二更,藍橋盃國賽來了這題,但是沒做出來,重新理解了一遍
dpi:以第i小的字元結尾的上公升子串行的種類數,dp從字串頭到尾遍歷,
字串中有若干個字元c,如\(...c_1...c_2\),靠後面出現的字元\(c_2\)必定包含了前面同一字元\(c_1\)的所有可能,\(c_2\)也有自己獨特的可能情況,如\(c_1\)和\(c_2\)間出現了比c小的其他字元等等,所以,最後答案就只用字元c最後一次出現的位置,該字元的貢獻,所以加乙個遇到的c字元的貢獻,記錄下來,之後再次出現時減去上一次的貢獻再加上這次的貢獻,這樣就只記錄了c字元最後乙個的值,不過中間的值可以被其他字元使用到,所以要記錄。
p3970 [tjoi2014]上公升子串行
題目描述
給定乙個只包含整數的序列(序列元素的絕對值大小不超過10^9),你需要計算上公升子串行的個數,滿足如下條件的稱之為乙個上公升子串行:
是原序列的乙個子串行
長度至少為2
所有元素都嚴格遞增
如果兩個上公升子串行相同,那麼只需要計算一次。例如:序列有4個上公升子串行,分別為,,
輸入格式
輸入的第一行是乙個整數n,表示序列長度。接下來一行是n個整數,表示序列。
輸出格式
輸出僅包含一行,即原序列有多少個上公升子串行。由於答案可能非常大,你只需要輸出答案模10^9+7的餘數。
輸入
4
1 2 3 3
輸出4
資料範圍
對於 30% 的資料,n ≤ 5000
對於 100% 的資料,n ≤ 10^5
如果不去重的話,dp[i]代表以第i小為結尾的上公升子串行數量,\(dp[i]=1+\sum_^dp[j]\) ,其中1是以a[i]作為為序列的數量,所以,用樹狀陣列很容易維護這個字首和。
當然,這樣還有重複,但不能直接除去重複的元素,當某元素第二次出現時,當前元素dp[b]中包括了第一次出現該元素時dp[a]裡的所有可能情況,所以減去重複的元素,也就是加上dp[b]中獨有的方案數,還有就是長度為1的序列不能包括,但是我們去重的時候如果x出現了k次,那麼x元素長度為1的情況已經只被記錄過一次,即最後答案中長度為1的元素個數=去重之後的元素個數。
#includeusing namespace std;
#define lowbit(x) ((x)&(-x))
const int inf=0x3f3f3f3f,mod=1e9+7,maxn=1e5+4;
int a[maxn],aa[maxn],tot,n;
int last[maxn];
unordered_mapmp;
int num[maxn];
inline int query(int pos)
return ans;
}inline void add(int pos,int val)
}int main()
return ans;
}inline void add(int pos,int val)
}int main() {
#ifdef local_ly
freopen("in.txt","r",stdin);
#endif
int t,cas=1;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d%d",&n,&m,&x,&y,&z);
for(int i=0;i未完待續...
上公升子串行
題目描述 乙個只包含非負整數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列,我們可以得到一些上公升的子串行,這裡1 i1 i2 ik n。例如 對於序列,有它的一些上公升子串行,如,等等。這些子串行中序列和最大的是子串行,它的所有元素的和為18。對於給定的乙個序列...
上公升子串行
time limit 1000ms memory limit 65536k 乙個只包含非負整數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列,我們可以得到一些上公升的子串行,這裡1 i1 i2 ik n。例如 對於序列,有它的一些上公升子串行,如,等等。這些子串行...
上公升子串行
submit statistic problem description 乙個只包含非負整數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列,我們可以得到一些上公升的子串行,這裡1 i1 i2 ik n。例如 對於序列,有它的一些上公升子串行,如,等等。這些子串行中...