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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ 1460 Pku2114 Boatherds

發布時間:2024/9/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1460 Pku2114 Boatherds 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

https://www.lydsy.com/JudgeOnline/problem.php?id=1460

思路

點分治。

(題面居然不說詢問的最大值為106106

Naive的O(qnlog2n)O(qnlog2?n)算法(1):

對每次詢問做一遍點分治,用two pointer查詢v1+v2<=kv1+v2<=kv1+v2>kv1+v2>kv1,v2v1,v2的個數,加上排序單次查詢就是O(nlogn)O(nlog?n)

BZOJ會TLE吧。

常數大了點的O(qnlogn)O(qnlog?n)算法(2):

對每次詢問做一遍點分治,用一個桶記錄值為v1v1的個數,然后查詢一下q?v2q?v2的值的個數。

BZOJ還是會TLE。

常數比較小的O(qnlogn)O(qnlog?n)算法(3):

在算法(2)的基礎上,離線回答詢問,不用對每次詢問做一遍點分治,只需要總體上做一遍點分治就可以了。

BZOJ 1000ms AC。

O(n2logn)O(n2log?n)算法(4):

把所有路徑長度都丟到桶里面,最后O(1)O(1)回答詢問。

BZOJ 4000ms以上 AC。

代碼

特別感謝yxc大佬的算法(1),(4)的代碼

算法(1)

#include<cstdio> #include<algorithm> #define il inline #define rg register #define N 10001 using namespace std; struct fk{int to,w,nxt;}e[N<<1]; int n,k,p,root,Max,ans,dis[N],top; int sz[N],maxv[N],head[N],cnt,vis[N]; il int read() {char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+ch-'0';return x*f; } il void add(int u,int v,int w){e[++cnt].to=v;e[cnt].nxt=head[u];e[cnt].w=w;head[u]=cnt;} il void get_size(int u,int fa) {sz[u]=1;maxv[u]=0;for(rg int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa&&!vis[e[i].to])get_size(e[i].to,u),sz[u]+=sz[e[i].to],maxv[u]=max(maxv[u],sz[e[i].to]); } il void get_root(int r,int u,int fa) {maxv[u]=max(maxv[u],sz[r]-sz[u]);if(Max>maxv[u])Max=maxv[u],root=u;for(rg int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa&&!vis[e[i].to])get_root(r,e[i].to,u); } il void get_dis(int u,int fa,int d) {dis[++top]=d;for(rg int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa&&!vis[e[i].to])get_dis(e[i].to,u,d+e[i].w); } il int calc(int rt,int d) {top=0;get_dis(rt,0,d);sort(dis+1,dis+top+1);int l=1,r=top,ret1=0,ret2=0;while(l<r){while(dis[l]+dis[r]>k&&l<r)r--;ret1+=r-l;l++;}l=1,r=top;while(l<r){while(dis[l]+dis[r]>=k&&l<r)r--;ret2+=r-l;l++;}return ret1-ret2; } il void dfs(int u) {Max=n;get_size(u,0);get_root(u,u,0);int rt=root;ans+=calc(rt,0);vis[rt]=1;for(rg int i=head[rt];i;i=e[i].nxt)if(!vis[e[i].to])ans-=calc(e[i].to,e[i].w),dfs(e[i].to); } int main() {n=read(),p=read();for(int i=1,u,v,w;i<n;i++)u=read(),v=read(),w=read(),add(u,v,w),add(v,u,w);while(p--){k=read();if(k==0){puts("Yes");continue;}dfs(1);printf(ans>0?"Yes\n":"No\n");for(rg int i=1;i<=n;i++)vis[i]=0;ans=0;} }

算法(2)

#include <cstdio> #include <cstring> #include <algorithm>const int maxn=10000; const int maxp=100; const int maxv=1000000; const int inf=0x3f3f3f3f;int read() {int x=0,f=1;char ch=getchar();while((ch<'0')||(ch>'9')){if(ch=='-'){f=-f;}ch=getchar();}while((ch>='0')&&(ch<='9')){x=x*10+ch-'0';ch=getchar();}return x*f; }int pre[maxn*2+10],now[maxn+10],son[maxn*2+10],tot,val[maxn*2+10]; int vis[maxn+10],f[maxn+10],size[maxn+10],n,p,bin[maxv+10]; int q,nowroot,nowsize,cnt,tmp[maxn+10],flag,deep[maxn+10];int ins(int a,int b,int c) {pre[++tot]=now[a];now[a]=tot;son[tot]=b;val[tot]=c;return 0; }int getc(int u,int fa) {size[u]=1;f[u]=0;int j=now[u];while(j){int v=son[j];if((v!=fa)&&(!vis[v])){getc(v,u);size[u]+=size[v];f[u]=std::max(f[u],size[v]);}j=pre[j];}f[u]=std::max(f[u],nowsize-size[u]);if(f[u]<f[nowroot]){nowroot=u;}return 0; }int getdeep(int u,int fa) {tmp[++cnt]=deep[u];int j=now[u];while(j){int v=son[j];if((v!=fa)&&(!vis[v])){deep[v]=deep[u]+val[j];getdeep(v,u);}j=pre[j];}return 0; }int calc(int u,int ud) {deep[u]=ud;cnt=0;getdeep(u,0);memset(bin,0,sizeof bin);int res=0;for(int i=1; i<=cnt; ++i){++bin[tmp[i]];}for(int i=1; i<=cnt; ++i){if(q>=tmp[i]){res+=bin[q-tmp[i]];}}return res>>1; }int solve(int u) {vis[u]=1;int ans=calc(u,0),j=now[u];while(j){int v=son[j];if((!vis[v])&&(!flag)){ans-=calc(v,val[j]);nowroot=0;nowsize=size[v];getc(v,0);solve(nowroot);}j=pre[j];}if(ans>0){flag=1;}return 0; }int main() {n=read();p=read();for(int i=1; i<n; ++i){int a=read(),b=read(),c=read();ins(a,b,c);ins(b,a,c);}f[0]=inf;while(p--){memset(vis,0,sizeof vis);q=read();flag=0;nowsize=n;nowroot=0;getc(1,0);solve(nowroot);if(flag){puts("Yes");}else{puts("No");}}return 0; }

算法(3)

#include <cstdio> #include <cstring> #include <algorithm>const int maxn=10000; const int maxp=100; const int maxv=1000000; const int inf=0x3f3f3f3f;int read() {int x=0,f=1;char ch=getchar();while((ch<'0')||(ch>'9')){if(ch=='-'){f=-f;}ch=getchar();}while((ch>='0')&&(ch<='9')){x=x*10+ch-'0';ch=getchar();}return x*f; }int pre[maxn*2+10],now[maxn+10],son[maxn*2+10],tot,val[maxn*2+10]; int vis[maxn+10],f[maxn+10],size[maxn+10],n,p,bin[maxv+10]; int q[maxn+10],ans[maxn+10],nowroot,nowsize,cnt,tmp[maxn+10],flag,deep[maxn+10];int ins(int a,int b,int c) {pre[++tot]=now[a];now[a]=tot;son[tot]=b;val[tot]=c;return 0; }int getc(int u,int fa) {size[u]=1;f[u]=0;int j=now[u];while(j){int v=son[j];if((v!=fa)&&(!vis[v])){getc(v,u);size[u]+=size[v];f[u]=std::max(f[u],size[v]);}j=pre[j];}f[u]=std::max(f[u],nowsize-size[u]);if(f[u]<f[nowroot]){nowroot=u;}return 0; }int getdeep(int u,int fa) {if(deep[u]>maxv){return 0;}tmp[++cnt]=deep[u];int j=now[u];while(j){int v=son[j];if((v!=fa)&&(!vis[v])){deep[v]=deep[u]+val[j];getdeep(v,u);}j=pre[j];}return 0; }int calc(int u,int ud,int op) {deep[u]=ud;cnt=0;getdeep(u,0);for(int i=1; i<=cnt; ++i){++bin[tmp[i]];}for(int k=1; k<=p; ++k){int nq=q[k],res=0;for(int i=1; i<=cnt; ++i){if(nq>=tmp[i]){res+=bin[nq-tmp[i]];if(nq==(tmp[i]<<1)){++res;}}}ans[k]+=op*(res>>1);}for(int i=1; i<=cnt; ++i){--bin[tmp[i]];}return 0; }int solve(int u) {vis[u]=1;calc(u,0,1);int j=now[u];while(j){int v=son[j];if(!vis[v]){calc(v,val[j],-1);nowroot=0;nowsize=size[v];getc(v,0);solve(nowroot);}j=pre[j];}return 0; }int main() {n=read();p=read();for(int i=1; i<n; ++i){int a=read(),b=read(),c=read();ins(a,b,c);ins(b,a,c);}f[0]=inf;for(int i=1; i<=p; ++i){q[i]=read();}flag=0;nowsize=n;nowroot=0;getc(1,0);solve(nowroot);for(int i=1; i<=p; ++i){if((q[i]==0)||(ans[i]>0)){puts("Yes");}else{puts("No");}}return 0; }

算法(4)

#include<cstdio> #include<algorithm> #include<iostream> #define il inline #define rg register #define N 10001 using namespace std; struct fk{int to,w,nxt;}e[N<<1]; int n,k,p,root,Max,ans,dis[N],top; int sz[N],maxv[N],head[N],cnt,vis[N],sum[1000001]; il int read() {char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+ch-'0';return x*f; } il void add(int u,int v,int w){e[++cnt].to=v;e[cnt].nxt=head[u];e[cnt].w=w;head[u]=cnt;} il void get_size(int u,int fa) {sz[u]=1;maxv[u]=0;for(rg int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa&&!vis[e[i].to])get_size(e[i].to,u),sz[u]+=sz[e[i].to],maxv[u]=max(maxv[u],sz[e[i].to]); } il void get_root(int r,int u,int fa) {maxv[u]=max(maxv[u],sz[r]-sz[u]);if(Max>maxv[u])Max=maxv[u],root=u;for(rg int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa&&!vis[e[i].to])get_root(r,e[i].to,u); }il void get_dis(int u,int fa,int d) {dis[++top]=d;for(rg int i=head[u];i;i=e[i].nxt)if(e[i].to!=fa&&!vis[e[i].to]&&d+e[i].w<=1e6)get_dis(e[i].to,u,d+e[i].w); } il void calc(int rt,int d,int t) {top=0;get_dis(rt,0,d);sort(dis+1,dis+top+1);for(int i=1;i<=top;i++)for(int j=i+1;j<=top;j++){if(dis[i]+dis[j]>1e6)break;sum[dis[i]+dis[j]]+=t?1:-1;} } il void dfs(int u) {Max=n;get_size(u,0);get_root(u,u,0);int rt=root;calc(rt,0,1);vis[rt]=1;for(rg int i=head[rt];i;i=e[i].nxt)if(!vis[e[i].to])calc(e[i].to,e[i].w,0),dfs(e[i].to); } int main() {n=read(),p=read();for(int i=1,u,v,w;i<n;i++)u=read(),v=read(),w=read(),add(u,v,w),add(v,u,w);dfs(1);while(p--){k=read();if(k==0){puts("Yes");continue;}printf(sum[k]?"Yes\n":"No\n");} }

轉載于:https://www.cnblogs.com/Canopus-wym/p/10376179.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的BZOJ 1460 Pku2114 Boatherds的全部內容,希望文章能夠幫你解決所遇到的問題。

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