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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【HNOI2019】部分题简要题解

發(fā)布時(shí)間:2024/4/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【HNOI2019】部分题简要题解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題意懶得寫(xiě)了
LOJ

Day 1 T1 魚(yú)

個(gè)人做法比較獵奇,如果有哪位大佬會(huì)證明能分享一下的話感激不盡。
題解:枚舉魚(yú)尾和魚(yú)身的交點(diǎn)D,將所有其他點(diǎn)按照到D的距離排序,距離相同的分一組。
感性的理解,對(duì)于每個(gè)點(diǎn)D,暴力枚舉距離相等的點(diǎn)對(duì)(B,C)。這樣總的數(shù)量不會(huì)很多。感覺(jué)仍然是\(O(n^2)\)級(jí)別的。
那么我們對(duì)枚舉的D,將所有的點(diǎn)對(duì)的中垂射線和點(diǎn)按照極角排序,掃一圈就能得到答案了。魚(yú)尾的部分也是利用掃描線,用叉積判斷可能會(huì)有問(wèn)題(轉(zhuǎn)過(guò)了180度),那么我們可以將其倍長(zhǎng),用極角的值來(lái)判即可。
精度要求比較高。

奇丑無(wú)比...

#include <bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;++i) #define fod(i,a,b) for(int i=a;i>=b;--i) #define N 2005 #define M 1000005 #define LL long long #define LT long double using namespace std; int n; LL ans; //geometry long double sqr(LL x) {LT v=x;return v*v; } namespace geometry {const long double pi=acos(-1);const long double eps=1e-15;struct node{LL x,y;node(LL _x=0,LL _y=0){x=_x,y=_y;}};node operator +(node x,node y) {return node(x.x+y.x,x.y+y.y);}node operator -(node x,node y) {return node(x.x-y.x,x.y-y.y);}long double angel(node x){long double v=atan2(x.y,x.x);if(v<0) v+=2*pi;return v;}LT dis2(node x,node y) {return sqr(x.x-y.x)+sqr(x.y-y.y);}LT crs(node x,node y) {return (LT)x.x*(LT)y.y-(LT)x.y*(LT)y.x;} } using namespace geometry;node d[N],a[N],dw[M]; LL c1[N],cnt[N]; LT ds[N]; int n1,px[N],fr[N],l,le; vector<int> pt[N];long double ag(int x) {if(x>l) return angel(d[px[x]])+2*pi;else return angel(d[px[x]]); } int pw(node x) {if(x.x>=0) return (x.y>=0)?1:4;else return (x.y>=0)?2:3; } bool cmp(int x,int y) {return ds[x]<ds[y];} bool cmp2(node x,node y) {int fx=pw(x),fy=pw(y);return (fx<fy||(fx==fy&&crs(x,y)>0)); } bool cmp3(int x,int y) {return cmp2(d[x],d[y]);} bool cmp4(node x,node y) {return dis2(x,node(0,0))<dis2(y,node(0,0));}bool eql(node x,node y) {return(!cmp2(x,y)&&!cmp2(y,x)); } int ed[N],mx,mn;LL query(int k) { l=0;fo(i,1,n) if(i!=k){d[++l]=a[i]-a[k];px[l]=l;ds[l]=dis2(a[i],a[k]);} sort(px+1,px+l+1,cmp);n1=0;fo(i,1,l) {if(i==1||abs(ds[px[i]]-ds[px[i-1]])>eps){cnt[++n1]=0;pt[n1].clear();}cnt[n1]++,pt[n1].push_back(px[i]),fr[px[i]]=n1;}if(l<5) return 0;le=0;fo(i,1,n1) {fo(j,0,cnt[i]-1){fo(k,j+1,cnt[i]-1){int u=pt[i][j],v=pt[i][k];if((d[u]+d[v]).x!=0||(d[u]+d[v]).y!=0) dw[++le]=d[u]+d[v];}}}memset(c1,0,sizeof(c1));sort(px+1,px+l+1,cmp3);sort(dw+1,dw+le+1,cmp2);int lst=0;fo(i,1,l) {if(i==1||!eql(d[px[i]],d[px[i-1]])){if(lst!=0) {sort(px+lst,px+i,cmp);fo(j,lst,i-1) ed[j]=i-1;}lst=i;}}if(lst!=0) {sort(px+lst,px+l+1,cmp);fo(j,lst,l) ed[j]=l;}lst=0;fo(i,1,le){if(i==1||!eql(dw[i],dw[i-1])){if(lst!=0) sort(dw+lst,dw+i,cmp4);lst=i;}}if(lst!=0) sort(dw+lst,dw+le+1,cmp4);int lp=1,rp=1;LL s1=0,sp=0;fo(i,1,l) px[i+l]=px[i];long double upg=angel(dw[1])+pi/2,dpg=angel(dw[1])+3*pi/2;while(lp<=2*l&&ag(lp)<upg+eps) lp++;rp=lp;while(rp<=2*l&&ag(rp)<dpg) rp++;for(int j=lp;j<rp;j++){sp-=(LL)c1[fr[px[j]]]*(LL)(c1[fr[px[j]]]-1);c1[fr[px[j]]]++;sp+=(LL)c1[fr[px[j]]]*(LL)(c1[fr[px[j]]]-1);}int j=1,ef=0;while(j<=l&&cmp2(d[px[j]],dw[1])) j++;if(j<=l&&eql(d[px[j]],dw[1])) ef=ed[j];else ef=0;LT di=dis2(dw[1],node(0,0));while(j<=ef&&di>=(LT)4*ds[px[j]]) j++;if(ef!=0) s1=s1+sp*(LL)2*(LL)(ef-j+1);mx=max(mx,le),mn=max(mn,n1);fo(i,2,le){if(i==1||!eql(dw[i],dw[i-1])){upg=angel(dw[i])+pi/2,dpg=angel(dw[i])+3*pi/2;while(rp<=2*l&&ag(rp)<dpg-eps){sp-=(LL)c1[fr[px[rp]]]*(LL)(c1[fr[px[rp]]]-1);c1[fr[px[rp]]]++;sp+=(LL)c1[fr[px[rp]]]*(LL)(c1[fr[px[rp]]]-1);rp++;}while(lp<=2*l&&ag(lp)<upg+eps) {sp-=(LL)c1[fr[px[lp]]]*(LL)(c1[fr[px[lp]]]-1);c1[fr[px[lp]]]--;sp+=(LL)c1[fr[px[lp]]]*(LL)(c1[fr[px[lp]]]-1);lp++;}while(j<=l&&cmp2(d[px[j]],dw[i])) j++;if(j<=l&&eql(d[px[j]],dw[i])) ef=ed[j];else ef=0;}LT di=dis2(dw[i],node(0,0));while(j<=ef&&di>=(LT)4*ds[px[j]]) j++;if(ef!=0) s1=s1+sp*(LL)2*(LL)(ef-j+1);} return s1; } int main() {cin>>n;fo(i,1,n) scanf("%lld%lld\n",&a[i].x,&a[i].y);ans=0;fo(i,1,n) {ans+=query(i);}printf("%lld\n",ans); }

Day 1 T3 多邊形

題解:觀察樣例可以發(fā)現(xiàn),最終狀態(tài)一定是n-3條邊都與n號(hào)點(diǎn)相連。
那么次數(shù)最少的操作一定每一次都是要連到n的
進(jìn)一步可以發(fā)現(xiàn),某些邊的操作一定在某條邊之后,先后關(guān)系可以構(gòu)成一個(gè)森林。
操作次數(shù)就是森林點(diǎn)數(shù),方案數(shù)就是森林的拓?fù)湫蚍N數(shù)。
現(xiàn)在提前給出一些操作,觀察這些操作在樹(shù)上的變化,要么直接刪去一個(gè)點(diǎn),要么改變一些父子關(guān)系,改變的個(gè)數(shù)只有常數(shù)個(gè),直接計(jì)算這些點(diǎn)對(duì)答案的影響即可。

用map來(lái)存標(biāo)號(hào),時(shí)間復(fù)雜度\(O(n\log n)\)

#include <bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;++i) #define fod(i,a,b) for(int i=a;i>=b;--i) #define N 100005 #define mo 1000000007 #define LL long long using namespace std; int mx[N],mi[N],n,m,n1,tp,ft[N],fn[N],t[N][2],ap[N][2],sz[N]; map<int,int> h[N]; LL f[N],js[N],ns[N],ny[N]; bool bz[N];LL C(int n,int m) {if(n<m) return 0;return js[n]*ns[m]%mo*ns[n-m]%mo; } LL nC(int n,int m) {if(n<m) return 0;return ns[n]*js[m]%mo*js[n-m]%mo; }void dfs(int k) {if(!k) return;dfs(t[k][0]),dfs(t[k][1]);sz[k]+=sz[t[k][0]]+sz[t[k][1]];f[k]=f[t[k][0]]*f[t[k][1]]%mo*C(sz[k]-1,sz[t[k][0]])%mo; }LL ksm(LL k,LL n) {LL s=1;for(;n;n>>=1,k=k*k%mo) if(n&1) s=s*k%mo;return s; } int main() {freopen("polygon.in","r",stdin);freopen("polygon.out","w",stdout);cin>>tp; cin>>n;js[0]=ns[0]=js[1]=ns[1]=ny[1]=1;fo(i,2,n) js[i]=js[i-1]*(LL)i%mo,ny[i]=(-ny[mo%i]*(LL)(mo/i)%mo+mo)%mo;fo(i,2,n) ns[i]=ns[i-1]*ny[i]%mo;memset(mi,107,sizeof(mi));fo(i,1,n-3){int x,y;scanf("%d%d",&x,&y);if(x>y) swap(x,y);if(y==n) {bz[i]=1;continue;}ap[i][0]=x,ap[i][1]=y;h[x][y]=i,h[y][x]=i;mx[x]=max(mx[x],y),mx[y]=max(mx[y],x);mi[x]=min(mi[x],y),mi[y]=min(mi[y],x);}fo(i,1,n-3){int x=ap[i][0],y=ap[i][1];if(bz[i]) continue;n1++,sz[i]=1;if(mx[x]>y){int w=(*h[x].upper_bound(y)).second;if(bz[w]) continue;ft[i]=w,fn[i]=0,t[w][0]=i;}else if(mi[y]<x){map<int,int>::iterator it=h[y].find(x);it--;int w=(*it).second;if(bz[w]) continue;ft[i]=w,fn[i]=1,t[w][1]=i;}}f[0]=1;LL ans=1,sp=0;fo(i,1,n-3) if(!bz[i]&&!ft[i]) {dfs(i);sp+=sz[i];ans=ans*f[i]%mo*C(sp,sz[i])%mo;}printf("%d",n1);if(tp) printf(" %lld",ans);printf("\n");cin>>m;fo(i,1,m){int x,y,w;scanf("%d%d",&x,&y);w=h[x][y];int n2=n1;LL s1=ans;if(!ft[w]){n2--;s1=s1*nC(sp,sz[w])%mo*ksm(f[w],mo-2)%mo;s1=s1*C(sp-1-sz[t[w][0]],sz[t[w][1]])%mo*f[t[w][1]]%mo;s1=s1*C(sp-1,sz[t[w][0]])%mo*f[t[w][0]]%mo;}else{int r=ft[w],p=fn[w];if(p!=0) printf("WA\n");s1=s1*ksm(f[r],mo-2)%mo;s1=s1*f[t[w][1]]%mo*f[t[r][1]]%mo*C(sz[t[w][1]]+sz[t[r][1]],sz[t[w][1]])%mo*f[t[w][0]]%mo*C(sz[r]-1,sz[t[w][0]])%mo;}printf("%d",n2);if(tp) printf(" %lld",s1);printf("\n");} }

Day 2 T1 校園旅行

題解:考慮一個(gè)暴力DP,\(f[x][y]\)表示x,y是否能通過(guò)回文串到達(dá),枚舉兩邊的出邊,按照BFS的順序轉(zhuǎn)移,時(shí)間復(fù)雜度\(O(m^2)\)
考慮優(yōu)化,我們將邊分類,要么是連接不同顏色的邊,要么是連接相同顏色的邊。
只取出連接相同顏色的邊,考慮每一個(gè)連通塊,如果它是個(gè)二分圖,那么保留一棵生成樹(shù)即可(因?yàn)槠ヅ渑渲慌c奇偶性有關(guān),數(shù)量不同可以在一條邊反復(fù)橫跳滿足)。如果不是,那么奇偶性可以改變,可以任意匹配,那么保留一棵生成樹(shù),再連上一個(gè)自環(huán)表示奇環(huán)的情況。對(duì)于連接不同顏色的邊的聯(lián)通塊,它顯然是二分圖,直接保留生成樹(shù)即可。
連邊采用并查集,時(shí)間復(fù)雜度\(O(m\alpha(n))\)
這樣邊數(shù)也降為了\(O(n)\)級(jí)別,暴力DP的時(shí)間復(fù)雜度就變成了\(O(n^2)\)

#include <bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;++i) #define fod(i,a,b) for(int i=a;i>=b;--i) #define N 5005 #define L 25000005 using namespace std; int q,n,m,c[N],cnt,lp,m1; bool f[N][N]; int d[L][2],f1[N],g[N],a[N][2][N],le; bool bp[N],bc[N]; void bfs() {fo(i,1,n) f[i][i]=1,d[++le][0]=i,d[le][1]=i;int l=0,r=le;while(l<r){l++;int x=d[l][0],y=d[l][1];fo(e,0,1){fo(i,1,a[x][e][0]){int u=a[x][e][i];fo(j,1,a[y][e][0]){int v=a[y][e][j];if(!f[u][v]) f[u][v]=f[v][u]=1,d[++r][0]=u,d[r][1]=v;}}}}n++,n--; } int getf(int k) {if(f1[k]==k||!f1[k]) return k;int p=getf(f1[k]);bc[k]^=bc[f1[k]];return f1[k]=p; } int getf1(int k) {if(g[k]==k||!g[k]) return k;return g[k]=getf1(g[k]); } void link(int x,int y) {a[x][c[y]][++a[x][c[y]][0]]=y; } int main() {freopen("tour.in","r",stdin);freopen("tour.out","w",stdout);cin>>n>>m>>q;scanf("\n");fo(i,1,n){char ch=getchar();c[i]=ch-'0';}fo(i,1,m){int x,y;scanf("%d%d",&x,&y);if(c[x]==c[y]){int fx=getf(x),fy=getf(y);if(fx!=fy) {f1[fy]=fx,bp[fx]|=bp[fy],bc[fy]=bc[x]^1^bc[y]^bc[fx];link(x,y),link(y,x);f[x][y]=f[y][x]=1;d[++le][0]=x,d[le][1]=y;}else if(bc[x]==bc[y]) bp[fx]=1;}else{int fx=getf1(x),fy=getf1(y);if(fx!=fy) g[fy]=fx,link(x,y),link(y,x);}}fo(i,1,n) if(getf(i)==i&&bp[i]) link(i,i);bfs();fo(i,1,q) {int x,y;scanf("%d%d",&x,&y);if(f[x][y]) printf("YES\n");else printf("NO\n");} }

Day 2 T2 白兔之舞

考慮枚舉走了i步,容易得出\(Ans_t=\sum\limits_{i=0}^{L}[(i-t)\%k==0]{L\choose i}W^i_{x,y}\)
根據(jù)單位根反演的公式\([n|k]={1\over n}\sum\limits_{i=0}^{n-1}\omega_n^{ki}\)
這里單位根我們找一個(gè)p的原根,然后取其(p-1)/k次作為K次單位根
代入,交換主體可得
\(Ans_t=\sum\limits_{j=0}^{k-1}\omega_k^{-jt}\sum\limits_{i=0}^{L}{L\choose i}\left(\omega_k^j\right)^iW^i_{x,y}\)
后面的部分用二項(xiàng)式定理就是\(\left(\omega_k^jW+I\right)^L_{x,y}\),枚舉j,用矩陣快速冪做
前面的\(\omega_k^{-jt}\),一個(gè)經(jīng)典的套路就是將\(jt\)拆成\({j+t\choose 2}-{j\choose 2}-{t\choose 2}\)
這樣剩下的就是一個(gè)卷積了,用任意模數(shù)NTT/MTT優(yōu)化即可。
時(shí)間復(fù)雜度\(O(n^3k\log L+k\log k)\)

#include <bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;++i) #define fod(i,a,b) for(int i=a;i>=b;--i) #define N 3 #define M 262144 #define L 18 #define LL long long using namespace std; int n,m,r,st,ed,mo,P; LL wp[M+1]; int d[100]; LL ksm(LL k,LL n) {LL s=1;for(;n;n>>=1,k=k*k%mo) if(n&1) s=s*k%mo;return s; } bool pd(LL v) {fo(i,1,d[0]) if(ksm(v,(mo-1)/d[i])==1) return 0;return 1; }namespace polynomial {const double pi=acos(-1);struct Z{double x,y;Z(double _x=0,double _y=0){x=_x,y=_y;}};Z operator +(Z a,Z b) {return Z(a.x+b.x,a.y+b.y);}Z operator -(Z a,Z b) {return Z(a.x-b.x,a.y-b.y);}Z operator *(Z a,Z b) {return Z(a.x*b.x-a.y*b.y,a.y*b.x+a.x*b.y);}Z wi[M+1],u1[M+1],u2[M+1],u3[M+1],u4[M+1],ux[M+1],uy[M+1];int bit[M+1];void prp(){fo(i,0,M) {bit[i]=(bit[i>>1]>>1)|((i&1)<<(L-1));wi[i]=Z(cos(i*2*pi/M),sin(i*2*pi/M));}}void DFT(Z *a,bool pd){fo(i,0,M-1) if(i<bit[i]) swap(a[i],a[bit[i]]);Z v;for(int h=1,m=2,l=M>>1;m<=M;l>>=1,h=m,m<<=1){for(int j=0;j<M;j+=m){Z *x=a+j,*y=a+j+h,*w=(!pd)?wi:wi+M;fo(i,0,h-1){Z v=*y * *w;*y=*x-v,*x=*x+v;x++,y++,w+=(!pd)?l:-l;}}}if(pd) fo(i,0,M-1) a[i].x/=M,a[i].y/=M;}void rec(Z *a,Z *x,Z *y){fo(i,0,M-1){x[i].x=(a[i].x+a[(M-i)%M].x)/2;x[i].y=(a[i].y-a[(M-i)%M].y)/2;y[i].x=(a[i].y+a[(M-i)%M].y)/2;y[i].y=(a[(M-i)%M].x-a[i].x)/2;}}void mul(LL *a,LL *b){fo(i,0,M-1) ux[i]=uy[i]=u1[i]=u2[i]=u3[i]=u4[i]=Z(0,0);fo(i,0,M-1) {ux[i].x=a[i]/P,ux[i].y=a[i]%P;uy[i].x=b[i]/P,uy[i].y=b[i]%P;}prp();DFT(ux,0),DFT(uy,0);rec(ux,u1,u2),rec(uy,u3,u4);fo(i,0,M-1){ux[i]=u1[i]*u3[i]+(u1[i]*u4[i])*Z(0,1);uy[i]=u2[i]*u4[i]+(u2[i]*u3[i])*Z(0,1);}DFT(ux,1),DFT(uy,1);fo(i,0,M-1){LL u=ux[i].x+mo+0.5,v=ux[i].y+mo+0.5,p=uy[i].y+mo+0.5,q=uy[i].x+mo+0.5;u%=mo,v%=mo,p%=mo,q%=mo;a[i]=((u*P%mo*P%mo+(v+p)%mo*P%mo+q)%mo+mo)%mo;}} } using namespace polynomial;namespace matrix {struct MT{LL a[3][3];}ac,ua;MT operator *(MT &a,MT &b){MT c;memset(c.a,0,sizeof(c.a));fo(i,0,n-1)fo(k,0,n-1)fo(j,0,n-1) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mo;return c;}MT kst(MT &a,LL x){MT s;memset(s.a,0,sizeof(s.a));fo(i,0,n-1) s.a[i][i]=1;for(;x;x>>=1,a=a*a) if(x&1) s=s*a;return s;} } using namespace matrix; LL a[M+1],b[M+1];int main() {freopen("dance.in","r",stdin);freopen("dance.out","w",stdout);cin>>n>>m>>r>>st>>ed>>mo;P=sqrt(mo);fo(i,0,n-1) fo(j,0,n-1) scanf("%lld",&ac.a[i][j]);int n1=mo-1;fo(i,2,P){if(n1%i==0){d[++d[0]]=i;while(n1%i==0) n1/=i;}}wp[0]=1;for(wp[1]=2;!pd(wp[1]);wp[1]++);wp[1]=ksm(wp[1],(mo-1)/m);fo(i,2,m) wp[i]=wp[i-1]*wp[1]%mo;fo(i,0,m-1){fo(x,0,n-1) fo(y,0,n-1) ua.a[x][y]=ac.a[x][y]*wp[i]%mo;fo(x,0,n-1) ua.a[x][x]++;ua=kst(ua,r);a[i]=ua.a[st-1][ed-1]*wp[(LL)i*(LL)(i-1)/2%m]%mo;}fo(i,0,2*m-2) b[2*m-i]=wp[(m-(LL)i*(LL)(i-1)/2%m)%m];mul(a,b);LL ns=ksm(m,mo-2);fo(i,0,m-1) printf("%lld\n",wp[(LL)i*(LL)(i-1)/2%m]*ns%mo*a[2*m-i]%mo); }

Day 2 T3 序列

題解:可以發(fā)現(xiàn),最優(yōu)策略是將原序列分成若干段,每一段取它們的均值,并且均值應(yīng)該遞增。
進(jìn)一步的,記S[i]為a的1~i前綴和,我們將點(diǎn)\((i,S[i])\)放到平面上,求一個(gè)下凸殼,相鄰點(diǎn)的連線斜率就是這一段取的均值。用單調(diào)棧來(lái)做,就可以做到\(O(nm)\)
考慮優(yōu)化,修改一個(gè)位置相當(dāng)于后綴的所有點(diǎn)整體下移/上移,我們預(yù)處理出前綴凸殼和后綴凸殼(單調(diào)棧構(gòu)成樹(shù)形結(jié)構(gòu),總的個(gè)數(shù)是\(O(n)\)的),現(xiàn)在相當(dāng)于做一個(gè)凸殼合并,我們?cè)谇熬Y凸殼上二分,再相應(yīng)的在后綴凸殼上二分找到最左的一個(gè)連接后滿足下凸性的點(diǎn),判斷前綴凸殼此時(shí)是否也是凸的相應(yīng)修改二分區(qū)間即可。(二分實(shí)際上可以用樹(shù)上倍增來(lái)實(shí)現(xiàn))
時(shí)間復(fù)雜度\(O(m\log ^2n)\)
實(shí)現(xiàn)上細(xì)節(jié)比較多

#include <bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;++i) #define fod(i,a,b) for(int i=a;i>=b;--i) #define N 100005 #define LL long long #define LT unsigned long long #define mo 998244353 using namespace std; LL a[N],ny[N],s2[N],sm[N],sr[N],ans[N]; LT s[N]; int n,m,st[N],top,f[N][19],ask[N][2],qs[N]; bool pd(int x,int y,int z) {return (s[y]-s[x])*(LT)(z-y)>(s[z]-s[y])*(LT)(y-x); } bool pd2(int x,int y,int z,LL xd) {return (s[y]-s[x]+xd)*(LT)(z-y)>(s[z]-s[y])*(LT)(y-x); } bool pd3(int x,int y,int z,LL xd) {return (s[y]-s[x])*(LT)(z-y)>(s[z]-s[y]+xd)*(LT)(y-x); } LL calc(LL v,int x,int y) {if(x>=y) return 0;return ((s2[y]-s2[x]+mo)%mo+v*v%mo*(LL)(y-x)%mo-(LL)2*((s[y]-s[x])%mo)%mo*v%mo+mo+mo)%mo; } LL calc2(LL v,int x,int y,int k,LL xd) {if(x>=y) return 0;LL u=(s2[y]-s2[x]-a[k]*a[k]%mo+(a[k]+xd)*(a[k]+xd)%mo+mo+mo)%mo;return (u+v*v%mo*(LL)(y-x)%mo-((LL)2*((LL)((s[y]-s[x])%mo)+xd)%mo*v%mo+mo)%mo+mo)%mo; } bool pd1(int x,int y,LL xd,int k) {int l=1,r=top,mid;while(l+1<r){mid=(l+r)>>1;if(pd2(y,st[mid],st[mid-1],xd)) r=mid;else l=mid;}if(r<=l||!pd2(y,st[r],st[r-1],xd)) mid=r;else mid=l;return (!pd3(x,y,st[mid],xd)); } int wz(int y,LL xd,int k) {int l=1,r=top,mid;while(l+1<r){mid=(l+r)>>1;if(pd2(y,st[mid],st[mid-1],xd)) r=mid;else l=mid;}if(r<=l||!pd2(y,st[r],st[r-1],xd)) mid=r;else mid=l;return st[mid]; } LL query(int k,LL xd) {int p=f[k-1][0],q=k-1;for(int j=18;q>0&&!pd1(p,q,xd,k);){while(j&&pd1(f[p][j],f[q][j],xd,k)) j--;p=f[p][j],q=f[q][j];}int w=wz(q,xd,k);LL v=(s[w]-s[q]+xd)%mo*ny[w-q]%mo;return (calc(v,q,k-1)+calc2(v,k-1,w,k,xd)+sm[q]+sr[w])%mo; } bool cmp(int x,int y) {return ask[x][0]<ask[y][0]; } int main() {freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);cin>>n>>m;st[++top]=0;ny[1]=1;fo(i,2,n) ny[i]=(-ny[mo%i]*(LL)(mo/i)%mo+mo)%mo;fo(i,1,n) scanf("%lld",&a[i]),s[i]=s[i-1]+a[i],s2[i]=(s2[i-1]+a[i]*a[i]%mo)%mo;st[top=1]=0;fo(i,1,n){while(top>1&&pd(st[top-1],st[top],i)) top--;st[++top]=i;f[i][0]=st[top-1];sm[i]=(sm[f[i][0]]+calc((s[i]-s[f[i][0]])%mo*ny[i-f[i][0]]%mo,f[i][0],i))%mo;}fo(j,1,18) fo(i,1,n) f[i][j]=f[f[i][j-1]][j-1];printf("%lld\n",sm[n]);fo(i,1,m){scanf("%d%d",&ask[i][0],&ask[i][1]);qs[i]=i;}sort(qs+1,qs+m+1,cmp);memset(st,0,sizeof(st)),top=0;int j=m;fod(i,n,1){while(top>1&&pd(i,st[top],st[top-1])) top--;st[++top]=i;sr[i]=sr[st[top-1]];if(top>1) sr[i]=(sr[i]+calc((s[st[top-1]]-s[i])%mo*ny[st[top-1]-i]%mo,i,st[top-1]))%mo;while(j>0&&ask[qs[j]][0]==i) {ans[qs[j]]=query(i,ask[qs[j]][1]-a[i]);j--;}}fo(i,1,m) printf("%lld\n",ans[i]); }

轉(zhuǎn)載于:https://www.cnblogs.com/BAJimH/p/10690153.html

總結(jié)

以上是生活随笔為你收集整理的【HNOI2019】部分题简要题解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。