LibreOJ

摘要:
题目链接很明显的2SAT问题,和树上距离有关显然要考虑树分治。由于2-SAT不具有容斥性,点分治不方便处理,不过我们可以边分治。

题目链接

很明显的2SAT问题,和树上距离有关显然要考虑树分治。由于2-SAT不具有容斥性,点分治不方便处理,不过我们可以边分治。

边分治,分治过程中对每条边t左右两侧各建立一棵线段树,线段树上每个区间结点u(设代表的区间范围为[l,r])开两个条件结点p[u][0]和p[u][1],分别代表”边t该侧管辖范围内与t的该侧端点距离在[l,r]之间的点是否全不接入/全都接入“,每个结点和它的两个儿子建立约束条件p[u][0]->p[l(u)][0],p[u][0]->p[r(u)][0],p[u][1]->p[l(u)][1],p[u][1]->p[r(u)][1]。对于边t管辖范围内的每个结点x(设x代表接入了该结点,!x代表不接入该结点),设它到边t的该侧端点的距离为d,则它要与该侧线段树上距离为d的结点u建立约束条件p[u][0]->x,p[u][1]->!x,并与另一侧线段树上距离范围在[L-(d+len(t)),R-(d+len(t))]内的结点u建立可能的四种约束条件{x->p[u][0],x->p[u][1],!x->p[u][0],!x->p[u][1]},然后跑2-SAT就行了。

由于边分治最多往下递归$O(logn)$层,每层上的每个结点最多与线段树上$O(logn)$个结点连边,所以总复杂度为$O(nlog^2n)$

1 #include<bits/stdc++.h>
2 using namespacestd;
3 typedef long longll;
4 const int N=2e5+10,inf=0x3f3f3f3f;
5 structTWO_SAT {
6     int n,hd[N*40],ne,mk[N*40],sta[N*40],tp;
7     struct E {int v,nxt;} e[N*80];
8     void link(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
9     void link(int u,int v,int f,intg) {
10         link(u<<1|f,v<<1|g);
11         link(v<<1|(!g),u<<1|(!f));
12 }
13     void init(int_n) {
14         n=_n,ne=tp=0;
15         for(int i=0; i<=(n<<1|1); ++i)mk[i]=0,hd[i]=-1;
16 }
17     bool dfs(intu) {
18         if(mk[u^1])return 0;
19         if(mk[u])return 1;
20         mk[u]=1,sta[tp++]=u;
21         for(int i=hd[u]; ~i; i=e[i].nxt)if(!dfs(e[i].v))return 0;
22         return 1;
23 }
24     boolcheck() {
25         for(int i=1; i<=n; ++i)mk[i]=0;
26         for(int i=1; i<=n; ++i)if(!mk[i<<1]&&!mk[i<<1|1]) {
27                 tp=0;
28                 if(!dfs(i<<1)) {
29                     for(; tp; mk[sta[--tp]]=0);
30                     if(!dfs(i<<1|1))return 0;
31 }
32 }
33         return 1;
34 }
35 } twosat;
36 #define l(u) ch[u][0]
37 #define r(u) ch[u][1]
38 #define mid ((l+r)>>1)
39 structSegtree {
40     int ch[N*40][2],RT[N],p[N*40][2],id[N],tot,tot2;
41     int newnode() {int u=++tot; l(u)=r(u)=0; returnu;}
42     void init(intn) {
43         tot=tot2=0;
44         for(int i=1; i<=n; ++i)id[i]=++tot2;
45 }
46     void build(int& u,int l,intr) {
47         u=newnode();
48         p[u][0]=++tot2,p[u][1]=++tot2;
49         if(l==r)return;
50         build(l(u),l,mid),build(r(u),mid+1,r);
51         twosat.link(p[u][0],p[l(u)][0],1,1),twosat.link(p[u][0],p[r(u)][0],1,1);
52         twosat.link(p[u][1],p[l(u)][1],1,1),twosat.link(p[u][1],p[r(u)][1],1,1);
53 }
54     void upd1(int u,int v,int f,int g,int L,int R,int l,intr) {
55         if(l>=L&&r<=R) {twosat.link(v,p[u][g],f,1); return;}
56         if(l>R||r<L)return;
57         upd1(l(u),v,f,g,L,R,l,mid),upd1(r(u),v,f,g,L,R,mid+1,r);
58 }
59     void upd2(int u,int v,int x,int l,intr) {
60         if(l==r) {
61             twosat.link(p[u][0],v,1,0);
62             twosat.link(p[u][1],v,1,1);
63             return;
64 }
65         x<=mid?upd2(l(u),v,x,l,mid):upd2(r(u),v,x,mid+1,r);
66 }
67 } tree;
68 struct E {intv,c,nxt;} e[N];
69 inta[N],hd[N],ne,n,m,siz[N],vis[N],tot,RT,mx,mxd,ds[N],Ll,Rr,rt[N],Mxd[N];
70 void link(int u,int v,int c) {e[ne]= (E) {v,c,hd[u]},hd[u]=ne++;}
71 vector<E>g[N];
72 void rebuild(int u,intf) {
73     int w=u;
74     for(int i=hd[u]; ~i; i=e[i].nxt) {
75         int v=e[i].v;
76         if(v==f)continue;
77 rebuild(v,u);
78         g[w].push_back({v,1,0});
79         if(~e[i].nxt&&~e[e[i].nxt].nxt)g[w].push_back({++tot,0,0}),w=tot;
80 }
81 }
82 voidrebuild() {
83     tot=n,rebuild(1,0);
84     memset(hd,-1,sizeof hd),ne=0;
85     for(int i=1; i<=tot; ++i) {
86         for(int j=0; j<g[i].size(); ++j)
87 link(i,g[i][j].v,g[i][j].c),link(g[i][j].v,i,g[i][j].c);
88 g[i].clear();
89 }
90 }
91 void getrt(int u,int f,intsz) {
92     siz[u]=1;
93     for(int i=hd[u]; ~i; i=e[i].nxt) {
94         int v=e[i].v;
95         if(vis[i]||v==f)continue;
96         getrt(v,u,sz),siz[u]+=siz[v];
97         int t=max(siz[v],sz-siz[v]);
98         if(t<mx)mx=t,RT=i;
99 }
100 }
101 void getdis(int u,int f,intd) {
102     ds[u]=d,mxd=max(mxd,d);
103     for(int i=hd[u]; ~i; i=e[i].nxt) {
104         int v=e[i].v,c=e[i].c;
105         if(vis[i]||v==f)continue;
106         getdis(v,u,d+c);
107 }
108 }
109 void buildedge(int u,int f,intt) {
110     tree.upd2(rt[t],tree.id[u],ds[u],0,Mxd[t]);
111     for(int i=0; i<=3; ++i)if(a[u]>>i&1)
112             tree.upd1(rt[t^1],tree.id[u],i>>1&1,i&1,Ll-(ds[u]+e[t^1].c),Rr-(ds[u]+e[t^1].c),0,Mxd[t^1]);
113     for(int i=hd[u]; ~i; i=e[i].nxt) {
114         int v=e[i].v;
115         if(vis[i]||v==f)continue;
116 buildedge(v,u,t);
117 }
118 }
119 void cal(int t) {tree.build(rt[t],0,Mxd[t]=mxd);}
120 void solve(int u,int f,intsz) {
121     if(sz==1)return;
122     mx=inf,getrt(u,0,sz);
123     int t=RT;
124     vis[t]=vis[t^1]=1;
125     mxd=0,getdis(e[t].v,0,0),cal(t);
126     mxd=0,getdis(e[t^1].v,0,0),cal(t^1);
127     buildedge(e[t].v,0,t),buildedge(e[t^1].v,0,t^1);
128     int a=siz[e[t].v],b=sz-siz[e[t].v];
129     solve(e[t].v,RT,a),solve(e[t^1].v,t^1,b);
130 }
131 intmain() {
132     memset(hd,-1,sizeof hd),ne=0;
133     scanf("%d%d%d%d",&n,&m,&Ll,&Rr);
134     for(int i=1; i<n; ++i) {
135         intu,v;
136         scanf("%d%d",&u,&v);
137         link(u,v,0);
138         link(v,u,0);
139 }
140     while(m--) {
141         intu,f;
142         scanf("%d%d",&u,&f);
143         a[u]|=1<<f;
144 }
145 rebuild();
146     twosat.init(tot*30);
147 tree.init(tot);
148     solve(1,0,tot);
149     puts(twosat.check()?"YES":"NO");
150     return 0;
151 }

免责声明:文章转载自《LibreOJ》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇前端http请求和常见的几个请求技术做具体的讲解面试题:HashSet、TreeSet 和HashMap 的实现与原理下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

webpack打包(1)

Webpack可以处理js/json资源。生成环境比开发环境具有更多的功能来压缩代码。它可以将ES6模块化为浏览器在webpack.config中识别的模块操作命令npmiwebpackwebpack-cli-g npminit npmiwebpack-cli-D配置并运行webpack以将webpack.config.js文件打包...

CSS-顶部滚动进度条

Documentbody{background-image:linear-gradient(torighttop,#f0050%,#ece50%);background-repeat:no-repeat;height:300vh;position:relative;background-size:100%calc(100%-100vh+5px);}body:...

element 导航菜单 控制路由跳转

处理中心&lt;我的平台&lt;templateslot=“title”&gt;选项1&lt;el menu itemindex=“2-4-3”&gt;选项3&lt;消息中心&lt;el menu itemindex=“4”&gt;//www.ele.me“rel=”externalnofall...

Jboss

同时,为了扩大JBoss的企业市场,JBoss已经签署了许多渠道合作伙伴。2004年6月,JBoss宣布JBoss应用服务器已通过Sun公司的J2EE认证。这是JBoss应用服务器历史上最重要的里程碑。JBossAOP 1.0于2004年10月发布。这也证实了JBoss是一家创新型公司。JBoss应用服务器5.0于2008年12月6日正式发布。新版本的应用服...

如何下载Chrome离线版EXE安装文件和MSI版安装文件

对于Chrome的稳定版本(官方版本),您只需添加“?”在Chrome的“最终用户许可协议”页面上的链接之后?Standalone=1对于Beta版和开发版Chrome,只需记住以下地址:http://dl.google.com/chrome/install/{versionnumber}/crome_安装程序中的版本号。exe表示要下载的Chrome版本号...

ERROR [IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序

使用C#生成应用程序以及读取和写入dbfs时,打开方法error[IM002][Microsoft][ODBC驱动程序管理器]中发生错误。找不到数据源名称,也未指定默认驱动程序。这个程序以前使用得很好。升级和修改后,在测试中发现了问题。为了追踪来源,我曾经是一个32位操作系统。现在我安装了一个win764位操作系统。从控制面板到管理工具再到ODBC驱动程序,...