NOIP提高組模擬賽10

2022-09-21 01:39:08 字數 2734 閱讀 2055

這套題咕咕咕咕咕了好久,還是決定先寫一點吧

從\(i\)到\(j\),在\(j\)處死了,那麼與從\(j\)到\(i\)死的次數是一樣的,也就是說可以向上走到\(lca\)一下的最後一次死的點,最後這一段統計一下需不需要多死一次就好了,樹上倍增記錄\(i\)的第\(2^\)級死亡點,1級死亡點\(dfs\)時候記錄路徑二分查詢即可

code

#include#include#includeusing namespace std;

const int maxn=200005;

struct edgee[maxn<<1|1];

int head[maxn],tot,n,k;

void add(int u,int v,int w)

int fa[maxn][21],dep[maxn],jd[maxn][21],top,rem[maxn];

long long cos[maxn],sum[maxn];

int ef(int x)

return rem[l-1];

}void dfs(int x,int fx)

--top;

}int lca(int x,int y)

int ask(int s,int t)

int main()_\sum^_max(ll[i][0]+rr[j][1],ll[i][1]+rr[j][0],ll[i][0]+rr[j][0])\)

並不好求,轉化一下

\(max(ll[i][0]+rr[j][1],ll[i][1]+rr[j][0],ll[i][0]+rr[j][0])=max(ll[i][1]-ll[i][0],rr[j][1]-rr[j][0],0)+ll[i][0]+rr[j][0]\)

設\(fl[i]=max(ll[i][1]-ll[i][0],0)\)

\(fr[i]=max(rr[i][1]-rr[i][0],0)\)

對答案貢獻轉化為

\(\displaystyle\sum^_\sum^_(ll[i][0]+rr[j][0]+max(fl[i],fr[j]))\)

對\(fl\)

\(fr\)排序,單調指標掃一遍就行了

code#include #include #includeusing namespace std;

const long long maxn=200005;

const long long mod=998244353;

long long n,a[maxn];

const long long inf=0x3f3f3f3f3f3f3f;

long long fl[maxn],fr[maxn],ll[maxn][2],rr[maxn][2];

long long dp[maxn][2],ans;

void work(int l,int r)

int mid=(l+r)>>1;work(l,mid);work(mid+1,r);

//向左,不選mid

dp[mid][0]=0;dp[mid][1]=-inf;

for(int i=mid-1;i>=l;--i)dp[i][0]=max(dp[i+1][0],dp[i+1][1]),dp[i][1]=dp[i+1][0]+a[i],ll[i][0]=max(dp[i][0],dp[i][1]);

//向左,選mid

dp[mid][0]=-inf;dp[mid][1]=a[mid];

for(int i=mid-1;i>=l;--i)dp[i][0]=max(dp[i+1][0],dp[i+1][1]),dp[i][1]=dp[i+1][0]+a[i],ll[i][1]=max(dp[i][0],dp[i][1]);

//向右,不選mid+1

dp[mid+1][0]=0;dp[mid+1][1]=-inf;

for(int i=mid+2;i<=r;++i)dp[i][0]=max(dp[i-1][0],dp[i-1][1]),dp[i][1]=dp[i-1][0]+a[i],rr[i][0]=max(dp[i][0],dp[i][1]);

//向右,選mid+1

dp[mid+1][0]=-inf;dp[mid+1][1]=a[mid+1];

for(int i=mid+2;i<=r;++i)dp[i][0]=max(dp[i-1][0],dp[i-1][1]),dp[i][1]=dp[i-1][0]+a[i],rr[i][1]=max(dp[i][0],dp[i][1]);

ll[mid][0]=0;ll[mid][1]=a[mid];

rr[mid+1][0]=0;rr[mid+1][1]=a[mid+1];

for(int i=l;i<=mid;++i)fl[i]=max(ll[i][1]-ll[i][0],0ll),ans=(ans+ll[i][0]*(r-mid))%mod;

for(int i=mid+1;i<=r;++i)fr[i]=max(rr[i][1]-rr[i][0],0ll),ans=(ans+rr[i][0]*(mid-l+1))%mod;

sort(fl+l,fl+mid+1);sort(fr+mid+1,fr+r+1);

int pl=l,pr=mid+1;

while(pl<=mid)

while(pr<=r)ans=(ans+fr[pr]*(mid-l+1))%mod,++pr;

return;

}int main()

這就是我咕咕咕咕咕了這篇題解這麼長時間的原因

這道題啊,暴力水了90pts,然後正解呢,咕咕咕咕咕咕

NOIP提高組模擬賽3

周圍大佬都說初中打過n遍,我乙個菜雞瑟瑟發抖。把斐波那契數列寫出來找了半天性質,用了半個多小時推出來 x兔子的父親,就是x減去是在斐波那契數列中最大的小於x的數 舉個栗子 13號兔子,應減去8,得到他的祖先5 10號兔子,應減去8,得到他的祖先2 預處理出斐波那契數列,然後讓ab中較大的到他的祖先,...

NOIP提高組模擬賽4

丹青千秋釀,一醉解愁腸 無悔少年枉,只願壯志狂 矩陣字首和加暴力 o n 2m 2 60pts有手就行 觀察資料範圍,猜測應該是求一種 o n 3 的演算法,想到之前做的題,應該是 n 2 枚舉行,n 處理乙個序列的答案,然後,就沒有然後了 對於乙個序列,求子段和為k的倍數,如何 o n 求解,考慮...

NOIP提高組模擬賽6

這題看著真熟啊,好像把之前的english,入陣曲雜糅了一下。首先,像入陣曲一樣計算出字首和 s 式子可以轉化為求 s r s l 1 equiv max mod k 像english一樣 用單調棧處理出以x為最大值的區間,分區間求解 每次列舉一側區間,已知max,只要知道另一側有多少與之餘數相同的...