日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

「AHOI / HNOI2018」转盘 解题报告

發布時間:2025/7/25 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 「AHOI / HNOI2018」转盘 解题报告 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

「AHOI / HNOI2018」轉盤

可能是我語文水平不太行...


首先可以猜到一些事實,這個策略一定可以被一個式子表示出來,不然帶修修改個錘子。

然后我們發現,可以枚舉起點,然后直接往前走,如果要等就等到它出現。

因為如果不等,一定要走超過一圈,這樣一定不如從它后面那個點當起點。

既然要等,不如我們就在起點等了,顯然這樣的等價的,于是我們可以搞出這個式子了。
\[ \min_{i=1}^n(\max_{j=i}^{i+n-1}S_j-j+i)+n-1 \]
這里我們把\(S\)倍長了

稍微放縮一下并扔掉不重要的東西,我們要維護的大概是這個東西
\[ \min_{i=1}^ni+(\max_{j=i}^{2n}T_j) \]
我們每次修改\(T_j\),然后詢問這個式子的值

考慮對\(j\)枚舉\(i\),有一些事實是

如果\(T_{p_1},T_{p_2},T_{p_3},\dots,T_{p_k}\)\(T\)的后綴最大值集合

我們的答案就是
\[ \min_{i=1}^kT_i+p_{i-1}+1 \]
后綴最大值可以以單調棧的形式表示出來

考慮在線段樹上維護

比如說,我們可以

我們每個節點維護一個右兒子最大值與左兒子整個后綴最大值集合連接成的答案集合。

有點抽象,舉個例子就是

比如有這樣的\(T\)

左兒子:5 4 3 1 右兒子:2 1 0

那么這個信息就是5 4 3 2這個集合的答案

也不一定非要這樣,但是這樣蠻方便的

維護這個信息得去左兒子上二分,所以這樣是\(\log^2 n\)

這個題,你發現,\(2n\)的區間中,右兒子內部不能產生貢獻(因為式子中\(\min\)的枚舉范圍是\(1\sim n\)的)

所以維護一下長為\(n\)的區間的答案,每次詢問的時候在\((n+1)\sim 2n\)里面找個最大值去問就可以了,注意到這個東西它可以從\(1\sim n\)的最大值里面獲得


Code:

#include <cstdio> #include <cctype> #include <vector> #include <algorithm> using std::min; using std::max; const int SIZE=1<<21; char ibuf[SIZE],*iS,*iT; //#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++) #define gc() getchar() template <class T> void read(T &x) {int f=0;x=0;char c=gc();while(!isdigit(c)) f|=c=='-',c=gc();while(isdigit(c)) x=x*10+c-'0',c=gc();if(f) x=-x; } const int N=2e5+10; const int inf=0x3f3f3f3f; int n,m,p,t[N]; int mx[N<<2],yuu[N<<2]; #define ls id<<1 #define rs id<<1|1 int qry(int id,int l,int r,int d) {if(l==r) return mx[id]>d?d+l:inf;int mid=l+r>>1;if(mx[rs]>d) return min(yuu[id],qry(rs,mid+1,r,d));else return qry(ls,l,mid,d); } void updata(int id,int l,int r) {mx[id]=max(mx[ls],mx[rs]);yuu[id]=qry(ls,l,l+r>>1,mx[rs]); } void upd(int id,int l,int r,int p,int d) {if(l==r){mx[id]=d;return;}int mid=l+r>>1;if(p<=mid) upd(ls,l,mid,p,d);else upd(rs,mid+1,r,p,d);updata(id,l,r); } void build(int id,int l,int r) {if(l==r){mx[id]=t[l];yuu[id]=inf;return;}int mid=l+r>>1;build(ls,l,mid),build(rs,mid+1,r);updata(id,l,r); } int main() {read(n),read(m),read(p);for(int i=1;i<=n;i++) read(t[i]),t[i]-=i;build(1,1,n);int ans=qry(1,1,n,mx[1]-n)+n;printf("%d\n",ans);for(int x,y,i=1;i<=m;i++){read(x),read(y);if(p) x^=ans,y^=ans;upd(1,1,n,x,y-x);printf("%d\n",ans=qry(1,1,n,mx[1]-n)+n);}return 0; }

2019.5.21

轉載于:https://www.cnblogs.com/butterflydew/p/10902479.html

總結

以上是生活随笔為你收集整理的「AHOI / HNOI2018」转盘 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。