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

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

生活随笔

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

编程问答

nssl1459-空间简单度【扫描线,线段树】

發(fā)布時(shí)間:2023/12/3 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nssl1459-空间简单度【扫描线,线段树】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

正題


題目大意

nnn個(gè)點(diǎn)的一顆樹(shù),合法路徑定義為一條路徑上每個(gè)點(diǎn)的編號(hào)相差大于KKK。求合法路徑數(shù)


解題思路

首先我們可以求不合法的路徑數(shù),這樣我們就有了K?nK*nK?n個(gè)不合法(即不能在同一個(gè)路徑上)的點(diǎn)對(duì)。

然后這題就和之前一題jzoj6276一樣了

大概就是用矩形表示不合法的路徑,之后用掃面線求矩形的面積并即可。


codecodecode

#pragma GCC optimize(2) %:pragma GCC optimize(3) %:pragma GCC optimize("Ofast") %:pragma GCC optimize("inline") #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> using namespace std; const int N=3e5+10; struct node{int to,next; }a[N*2]; struct line{int x,l,r,w; }l[N*40]; bool operator<(line x,line y) {return x.x<y.x;} int n,K,tot,cnt,num; int rfn[N],ed[N],f[N][21],dep[N]; int w[N*4],mark[N*4],ls[N]; long long ans; __attribute__((optimize("O3"))) inline int read() {int x=0,f=1; char c=getchar();while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();return x*f; } void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return; } void dfs(int x,int fa){rfn[x]=++cnt;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa)continue;dep[y]=dep[x]+1;f[y][0]=x;dfs(y,x);}ed[x]=cnt;return; } int LCA(int x,int y){for(int i=20;i>=0;i--)if(dep[f[y][i]]>dep[x])y=f[y][i];return y; } void addc(int x1,int x2,int y1,int y2){if(x1>x2)swap(x1,x2);if(y1>y1)swap(y1,y2);l[++num]=(line){x1,y1,y2,1};l[++num]=(line){x2+1,y1,y2,-1}; } void Ban(int x,int y){if(rfn[x]>rfn[y])swap(x,y);if(rfn[x]<=rfn[y]&&rfn[y]<=ed[x]){int top=LCA(x,y);if(rfn[top]!=1)addc(1,rfn[top]-1,rfn[y],ed[y]);if(ed[top]!=n)addc(rfn[y],ed[y],ed[top]+1,n);}else addc(rfn[x],ed[x],rfn[y],ed[y]);return; } void Change(int x,int L,int R,int l,int r,int val){if(L==l&&R==r){mark[x]+=val;if(mark[x])w[x]=r-l+1;else if(l==r)w[x]=0;else w[x]=w[x*2]+w[x*2+1];return;}int mid=(L+R)>>1;if(r<=mid)Change(x*2,L,mid,l,r,val);else if(l>mid)Change(x*2+1,mid+1,R,l,r,val);else Change(x*2,L,mid,l,mid,val),Change(x*2+1,mid+1,R,mid+1,r,val);if(mark[x])w[x]=R-L+1;else w[x]=w[x*2]+w[x*2+1];return; } int main() {freopen("data.in","r",stdin);int size = 256 << 20; //250Mchar*p=(char*)malloc(size) + size;__asm__("movl %0, %%esp\n" :: "r"(p) );n=read();K=read(); for(int i=1;i<n;i++){int x=read(),y=read();addl(x,y);addl(y,x);}dfs(1,1);for(int i=1;i<=20;i++)for(int j=1;j<=n;j++)f[j][i]=f[f[j][i-1]][i-1];for(int i=1;i<=n;i++)for(int j=i+1;j<=min(i+K,n);j++)Ban(i,j);sort(l+1,l+1+num);int z=1;for(int i=1;i<=n;i++){while(z<=num&&l[z].x<=i)Change(1,1,n,l[z].l,l[z].r,l[z].w),z++;ans+=w[1];}printf("%lld",1ll*n*(n-1)/2-ans+n); }

總結(jié)

以上是生活随笔為你收集整理的nssl1459-空间简单度【扫描线,线段树】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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