給出乙個數列a1,a2,...ana_1,a_2,...a_na1,a2,...an和k,pk,pk,p
設si,j=ai+ai+1+...+ajs_=a_i+a_+...+a_jsi,j=ai+ai+1+...+aj
answer=min(si,jmod p∣si,jmod p>=k)answer=min(s_\mod p|s_\mod p>=k)answer=min(si,jmodp∣si,jmodp>=k)
其中i<=ji<=ji<=j,min(si,jmod p∣si,jmod p>=k)min(s_\mod p|s_\mod p>=k)min(si,jmodp∣si,jmodp>=k)非空。
第一行乙個正整數n,k,p
第二行n個整數,表示乙個乙個數列a1,a2,...an
在第一行輸出answer
輸入 #1
7 2 171213
1511
1626
11
輸出 #1
2
【資料範圍】
在100%的資料中,1<=n<=100000,1<=k,p,ai<=10^8,i=1,2,...n
將數列求得模意義下的字首和s[0,1...,n], 按套路列舉s[j] (0<=j=k。
分情況, 若存在s[j]使得s[i]-s[j]>=k,則s[j]<=s[i]-k且0<=s[i]-k;
若存在s[j]使得s[i]-s[j]<0但s[i]-s[j]+p>=k,則s[j]<=s[i]-k+p
(注意,上述兩種情況不一定包含所有s[j])
將s[0,1,...,i-1]插入平衡樹,每次分類查詢然後更新答案。應該沒有問題吧。
**
#include#include#include#include#include#includeusing namespace std;const int n=100010;
int s[n];
int n,k,p;
setd;
int main ()
int h=*--d.upper_bound(s[i]+p-k);
ans=min(ans,s[i]-h+p);
d.insert(s[i]);
} printf("%d\n",ans);
return 0;
}
P1799 數列 NOI導刊2010提高(06)
這道題就是求通過刪除數字得到乙個新序列,從而與 1,2,3,4,序列所能形成最多的匹配。在題解翻到了兩種做法 傳統dp 設 dp i j 為從原序列中的前 i 位取 j 個數所能形成的最多匹配。注意 匹配的條件是 a i j 因為我們求的是新序列,新序列中第 j 位所期望的數字就是 j 如果成立,那...
P1807 最長路 NOI導刊2010提高(07)
設g為有n個頂點的有向無環圖,g中各頂點的編號為1到n,且當為g中的一條邊時有i j。設w i,j 為邊的長度,請設計演算法,計算圖g中 1,n 間的最長路徑。輸入格式 輸入檔案longest.in的第一行有兩個整數n和m,表示有n個頂點和m條邊,接下來m行中每行輸入3個整數a,b,v 表示從a點到...
P1807 最長路 NOI導刊2010提高(07)
設g為有n個頂點的有向無環圖,g中各頂點的編號為1到n,且當為g中的一條邊時有i j。設w i,j 為邊的長度,請設計演算法,計算圖g中 1,n 間的最長路徑。輸入格式 輸入檔案longest.in的第一行有兩個整數n和m,表示有n個頂點和m條邊,接下來m行中每行輸入3個整數a,b,v 表示從a點到...