輸入檔名為seq.in。
首先輸入n。
接下來輸入n個數,描述序列 a。
輸出檔名為seq.out。
輸出一行乙個整數代表答案。
7 0 35 40 45 56 65 94
對於30%的資料,n<=5000
對於60%的資料,n<=50000
對於100%的資料,n<=500000,0<=a[i]<=10^9
這題還是很有趣的
發現n只有這麼大,nlog是過的去的
考慮分治
在正中間畫一條分界線
確保選的區間跨過了這條分界線
然後列舉分界線左邊(或右邊)界,按四種情況討論,得出另一邊的邊界
討論最大和最小值在左右哪邊,共四種情況,統計答案即可
然後兩邊分別分治下去
#include#include#include#define fo(i,a,b) for(ll i=a;i<=b;i++)
#define fd(i,a,b) for(ll i=a;i>=b;i--)
#define n 501000
#define ll long long
#define mo 1000000007
using namespace std;
ll mx[n],mi[n],n;
ll a[n],ans,s[n];
void dg(ll l,ll r)
ll m=(l+r)/2;
s[m]=a[m];s[m+1]=a[m+1];
fd(i,m-1,l) s[i]=min(a[i],s[i+1]);
fd(i,m-1,l) s[i]=(s[i]+s[i+1])%mo;
fo(i,m+2,r) s[i]=min(a[i],s[i-1]);
fo(i,m+2,r) s[i]=(s[i]+s[i-1])%mo;
s[l-1]=0;
ll j=m+1,k=m+1;
ll jy=0,an=0,da=a[m],xi=a[m],xo=a[m+1],db=a[m+1];
fd(i,m,l)
ans=(ans+an)%mo;
da=xi=a[m+1];j=k=m;an=0;xo=db=a[m];
fo(i,m+1,r)
ans=(ans+an)%mo;
da=xi=a[m];j=k=m+1;an=0;xo=db=a[m+1];
fd(i,m,l)
ans=(ans+an)%mo;
da=xi=a[m+1];xo=db=a[m];j=k=m;an=0;
fo(i,m+1,r)
ans=(ans+an)%mo;
dg(l,m);dg(m+1,r);
}int main()
NOIP2017模擬 鴨舌
題目 小美喜歡吃鴨舌。有乙個 n 個點的樹,每個節點 i 第 i 個點上有 ai 個鴨舌。小美一開始處於 x 號點。每次小美可以選擇乙個與現在的點有邊的點而且那個點還有鴨舌,那麼小美會走到那個點並吃乙個鴨舌。要保證小美最後還是走到 x 號點。問小美最多能吃幾個鴨舌?輸入格式 輸入第一行乙個整數 n ...
NOIP2017模擬 區間
2017.11.3 t1 2032 樣例資料 輸入3 2 1 2 1 1 2 4 5輸出 2 6分析 這道題為什麼要放在t1 考得我懷疑人生。本來也只會暴力找,對於30 的資料我是這樣的 先離散化,再二維陣列記錄所有顏色的在每個位置的字首和,然後四層迴圈暴力查詢。而正解是 先離散化,再把每種顏色的每...
NOIP2017模擬A組模擬8 5 帶權排序
正著考慮是不太容易的,考慮其它對e p i 的貢獻。1.設有j i,aj ai 就可以有貢獻ai aj rj lj 1 2.設有j i,aj 就可以有貢獻ai ajr j lj 1 下列描述以1為準。現在不具體考慮aj 的值,而是從大體上考慮,j對a的值取 lj rj 的貢獻是乙個等差數列,對 rj...