雅禮集訓 2017 Day1 解題報告

2022-04-29 23:15:07 字數 2577 閱讀 7192

挺神仙的一題。涉及區間加、區間除、區間最小值和區間和。雖然標算就是暴力,但是複雜度是***的。

我們知道如果線段樹上的乙個結點,\(max=min\) 或者 \(max=min+1\) 並且 \(d|max\),是可以直接剪掉的。

我們定義線段樹上乙個結點的勢能為 \(\log(max-min)\),那麼我們每執行一次區間除,都會引起勢能的減小。

但是執行區間加時我們涉及 \(\log n\) 個結點,最差情況下會將它們的勢能恢復為 \(\log(max-min)\)

所以總時間複雜度就是勢能總和,不難分析為 \(o(n\log d+q\log n\log d)\)

類似的,我們可以分析區間開根區間加的時間複雜度,在此就不贅述了。

\(code\ below:\)

#include #include #define int long long

#define lson (rt<<1)

#define rson (rt<<1|1)

using namespace std;

const int maxn=100000+10;

const int inf=1e18;

int n,m,a[maxn],sum[maxn<<2],max[maxn<<2],min[maxn<<2],add[maxn<<2];

inline int read()

while(isdigit(ch))

return (f==1)?x:-x;

}inline void pushup(int rt)

inline void pushtag(int rt,int c,int len)

inline void pushdown(int rt,int len)

}void build(int l,int r,int rt)

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

build(l,mid,lson);

build(mid+1,r,rson);

pushup(rt);

}void update_plu(int l,int r,int c,int l,int r,int rt)

pushdown(rt,r-l+1);

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

if(l <= mid) update_plu(l,r,c,l,mid,lson);

if(r > mid) update_plu(l,r,c,mid+1,r,rson);

pushup(rt);

}void update_div(int l,int r,int c,int l,int r,int rt)

} pushdown(rt,r-l+1);

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

if(l <= mid) update_div(l,r,c,l,mid,lson);

if(r > mid) update_div(l,r,c,mid+1,r,rson);

pushup(rt);

}int query_min(int l,int r,int l,int r,int rt)

pushdown(rt,r-l+1);

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

if(l <= mid) ans=min(ans,query_min(l,r,l,mid,lson));

if(r > mid) ans=min(ans,query_min(l,r,mid+1,r,rson));

return ans;

}int query_sum(int l,int r,int l,int r,int rt)

pushdown(rt,r-l+1);

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

if(l <= mid) ans+=query_sum(l,r,l,mid,lson);

if(r > mid) ans+=query_sum(l,r,mid+1,r,rson);

return ans;

}signed main()

return 0;

}

構造題。

發現無解的情況就是全空的情況,特判掉即可。

現在考慮怎麼算出最少步數。

發現只要第 \(i\) 行有黑色,那麼第 \(i\) 列會在 \(tot_\) 步變成全黑,所以我們來構造一行全黑的,然後將整個棋盤染成黑色。

那麼每行取個最小值即可,累加一下。

\(code\ below:\)

#include using namespace std;

const int maxn=1000+10;

int n,m,h[maxn],l[maxn],ans,sum;

char s[maxn][maxn];

int main()

} if(!flag)

ans=n;

for(int i=1;i<=n;i++) ans=min(ans,n-h[i]+!l[i]);

for(int i=1;i<=n;i++) sum+=l[i]!=n;

printf("%d\n",ans+sum);

return 0;

}

6029 雅禮集訓 2017 Day1 市場

6029.雅禮集訓 2017 day1 市場 題目描述 從前有乙個 市場,在一位執政官到來之前都是非常繁榮的,自從他來了之後,發布了一系列奇怪的政令,導致 市場的衰落。有 n nn 個商販,從 0 n 1 0 sim n 10 n 1 編號,每個商販的商品有乙個 ai a ia i 有兩種政令 l,...

雅禮集訓 2017 Day2 解題報告

我怎麼知道這種題目都能構造樹形結構。根據高度構造一棵樹,在樹上倍增找到最大的小於約束條件高度的隔板,開乙個 vector 記錄一下,然後對於每個 vector 按照高度排序一下,樹形 dp 即可 code below include define pii pair define mp make pa...

雅禮集訓 2017 價

傳送門 乙個不太顯然的最小割做法。我們這麼連邊 源點向藥物連 infty p i 容量的邊,藥物向它對應的藥材連 infty 容量的邊,藥材向匯點連 infty 容量的邊。用源點的流量減去最小割,再負回來就可以求出答案了。怎麼理解呢?割掉一條邊表示不選其對應的藥物或藥材,我們發現最後的方案一定是完美...