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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

#loj3059 HNOI2019 序列

發布時間:2023/12/8 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 #loj3059 HNOI2019 序列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

據說是保序回歸問題?

業界都在用的算法是將序列分成若干段,然后每段取個平均值生成一個不降的b序列

至于為啥是對的?我也不知道啊

一開始想寫個主席樹

然后懶癌發作選擇了反復二分的咸魚做法

先考慮50分怎么做的,我們使用一個棧存儲所有的段,

然后每次插入一個段的時候保證單調棧中每一段全部是單調遞增的就ok了

提取一段的方差可以用平均數的平方減去平方的平均數來算

現在來考慮100分怎么搞

由于每次都是假如這個位置變成了xxx的修改,因此考慮將左側前綴和右側后綴的單調棧拼接在一起

將所有詢問離線,然后假定更改的元素不會引起右側單調棧的變化,然后嘗試將這個點插入到左側單調棧當中

使用二分而不是均攤的pop可以做到log的復雜度

此時我們得到了左側的段,然后假定此時我們得到的左邊界就是正確的,然后嘗試將這一整段插入到右側單調棧當中

借助二分法這一步的復雜度自然是log的

然后接著假定右側的邊界就是正確的邊界,那么以此為依據去二分左側

如此反復迭代若干次就可以得到正確的解了

局的這東西和單純形算法很像,都是隨機卡不掉但是構造就跪了的東西

但是事實上出題人為了卡掉僅僅二分一次的算法就竭盡全力的,所以迭代6,7次就能過了

#include<cstdio> #include<algorithm> #include<vector> using namespace std;const int N=1e5+10;typedef long long ll; typedef long double ld;const ll mod=998244353; ll inv[N];ll ansmid[N],ansleft[N],ansright[N]; int cur_round; inline void pre() {inv[0]=inv[1]=1;for(int i=2;i<N;i++)inv[i]=(mod-mod/i)*inv[mod%i]%mod; } struct data {ll cnt0;ll cnt1;ll cnt2;friend data operator +(data a,data b){return (data){a.cnt0+b.cnt0,a.cnt1+b.cnt1,(a.cnt2+b.cnt2)%mod};}friend data operator -(data a,data b){return (data){a.cnt0-b.cnt0,a.cnt1-b.cnt1,(a.cnt2+mod-b.cnt2)%mod};}friend bool operator <(data a,data b){if(cur_round)return (ld)(a.cnt1)/(a.cnt0)<(ld)(b.cnt1)/(b.cnt0);else return (ld)(a.cnt1)/(a.cnt0)>(ld)(b.cnt1)/(b.cnt0); }inline ll cval(){ll tval=cnt1%mod;(tval*=tval)%=mod;return (cnt2+tval*(mod-inv[cnt0]))%mod;} }st[N],sum[N];ll ansst[N];int tp;int n;int m; struct qry {int id;data tmp;data ori; }; vector <qry> vq[N];ll a[N]; inline void ins_ele(data tmp) {st[++tp]=tmp;while(tp>1&&st[tp]<st[tp-1])st[tp-1]=st[tp-1]+st[tp],tp--;sum[tp]=st[tp]+sum[tp-1];ansst[tp]=(st[tp].cval()+ansst[tp-1])%mod; } inline data fastpop(data qry,ll& mans,ll& mans2) {int l=0;int r=tp;while(l!=r){int mid=(l+r+1)>>1;if(st[mid]<(sum[tp]-sum[mid]+qry))l=mid;else r=mid-1;}mans2=(sum[tp]-sum[l]+qry).cval();mans=ansst[l];//printf("fast pop locte=%d %lld %lld\n",l,mans2,mans);return sum[tp]-sum[l]; } int main() {//freopen("mtst.in","r",stdin);pre();scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%lld",&a[i]);cur_round=1;for(int i=1;i<=n;i++)ins_ele((data){1,a[i],(a[i]*a[i])%mod});printf("%lld\n",ansst[tp]);for(int i=1,u,k;i<=m;i++){scanf("%d%d",&u,&k);data nw=(data){1,k,(ll)k*k%mod};vq[u].push_back((qry){i,nw,nw});} for(int z=1;z<=20;z++){// printf("z=%d,front:\n",z);cur_round=1;tp=0;for(int i=1;i<=n;i++){for(vector <qry> :: iterator it=vq[i].begin();it!=vq[i].end();++it)it->tmp=it->ori+fastpop(it->tmp,ansleft[it->id],ansmid[it->id]);ins_ele((data){1,a[i],a[i]*a[i]%mod});}cur_round=0;// printf("z=%d,back:\n",z);tp=0;for(int i=n;i>=1;i--){for(vector <qry> :: iterator it=vq[i].begin();it!=vq[i].end();++it)it->tmp=it->ori+fastpop(it->tmp,ansright[it->id],ansmid[it->id]);ins_ele((data){1,a[i],a[i]*a[i]%mod});}}for(int i=1;i<=m;i++)printf("%lld\n",(ansleft[i]+ansmid[i]+ansright[i])%mod);return 0; }

轉載于:https://www.cnblogs.com/sweetphoenix/p/10814987.html

總結

以上是生活随笔為你收集整理的#loj3059 HNOI2019 序列的全部內容,希望文章能夠幫你解決所遇到的問題。

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