nssl1459-空间简单度【扫描线,线段树】
生活随笔
收集整理的這篇文章主要介紹了
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)題。
- 上一篇: nssl1460-逛机房【bfs】
- 下一篇: 51nod-有限背包计数问题【dp】