「SDOI 2018」战略游戏
题目大意:
给一个$G=(V,E)$,满足$|V|=n$,$|E|=m$,且保证图联通,有Q个询问,每组询问有s个点,求图中有多少点满足:将其删去后,这s个点中存在一对点集$(a,b)$不联通且删去点不为s中的点。
$n,m,\sum s$均为$1e5$级别。
题解:
显然满足性质的点都是割点。
我们建一颗圆方树,然后考虑对于每组询问为所有点之间路径覆盖的割点数量。
用虚树+树剖维护即可。
不是很难,但考场上把点双写错,多调了1h。
代码:
- #include "bits/stdc++.h"
- using namespace std;
- inline int read() {
- int s=0,k=1;char ch=getchar();
- while (ch<'0'|ch>'9') ch=='-'?k=-1:0,ch=getchar();
- while (ch>47&ch<='9') s=s*10+(ch^48),ch=getchar();
- return s*k;
- }
- const int N=2e5+10;
- struct edges {
- int v;edges *last;
- };
- int n,m;
- int low[N],dfn[N],stk[N],bcc_cnt,top,idx,rt,son,cut[N],bel[N],pos[N];
- vector<int> bcc[N];
- int ga[N],fat[N],rid[N],size[N],heavy[N],tid[N],dfx,ncut[N],deep[N];
- struct Group{
- inline void Clear(){ecnt=edge;memset(head,0,sizeof head);}
- edges edge[N<<2],*head[N],*ecnt;
- inline void push(int u,int v){
- *ecnt=(edges){v,head[u]},head[u]=ecnt++;
- *ecnt=(edges){u,head[v]},head[v]=ecnt++;
- }
- inline void tarjan(int x,int fa) {
- low[x]=dfn[x]=++idx;
- for (edges *i=head[x];i;i=i->last) if ((fa^1)!=i-edge){
- if (!dfn[i->v]) {
- if (x==rt) ++son;
- stk[++top] = i-edge;
- tarjan(i->v,i-edge);
- if (low[i->v]>=dfn[x]) {
- int t=0;bcc_cnt++;
- bcc[bcc_cnt].clear();
- do {
- t=stk[top--];
- bcc[bcc_cnt].push_back(edge[t].v);
- }while (t!=i-edge);
- bcc[bcc_cnt].push_back(x);
- cut[x]=true;
- } else low[x]=min(low[i->v],low[x]);
- } else if (dfn[i->v]<low[x]){
- low[x] = dfn[i->v];
- }
- }
- }
- inline void tarjan(){
- rt=1;son=0;
- tarjan(1,-1);
- if (son>1) cut[1]=true;
- else cut[1]=false;
- }
- inline void dfs(int x,int fa) {
- size[x]=1;
- for (edges *i=head[x];i;i=i->last) if (i->v!=fa) {
- deep[i->v]=deep[x]+1;
- dfs(i->v,x);
- fat[i->v]=x;
- size[x]+=size[i->v];
- if (size[i->v]>size[heavy[x]])
- heavy[x]=i->v;
- }
- }
- inline void dfs(int x,int fa,int grand) {
- ga[x]=grand;
- tid[x]=++dfx;
- rid[dfx]=x;
- if (heavy[x]) {
- dfs(heavy[x],x,grand);
- for (edges *i=head[x];i;i=i->last) if (i->v!=fa&&i->v!=heavy[x])
- dfs(i->v,x,i->v);
- }
- }
- inline void dfs() {
- dfs(1,0);
- dfs(1,0,1);
- }
- }g[2];
- struct node {
- node (){lc=rc=NULL,val=0;}
- node *lc,*rc;
- int val;
- }tree[N*40],*tcnt=tree,*fina,*root;
- inline void update(node *u) {
- u->val=u->lc->val+u->rc->val;
- }
- inline void build (node *&u,int l,int r) {
- u=tcnt++;
- *u=node();
- if (l==r) {
- u->val=ncut[rid[l]];
- return ;
- }
- int mid=l+r>>1;
- build(u->lc,l,mid);
- build(u->rc,mid+1,r);
- update(u);
- }
- inline void update(node *&u,int l,int r,int x,int y) {
- if (u<fina) {
- node *t=tcnt++;
- *t=*u;
- u=t;
- }
- if (x<=l&&r<=y) {u->val=0;return ;}
- int mid=l+r>>1;
- if (y>mid) update(u->rc,mid+1,r,x,y);
- if (x<=mid) update(u->lc,l,mid,x,y);
- update(u);
- }
- inline int query(node *u,int l,int r,int x,int y) {
- if (!u->val) return 0;
- if (x<=l&&r<=y) return u->val;
- int mid=l+r>>1,ret=0;
- if (y>mid) ret+=query(u->rc,mid+1,r,x,y);
- if (x<=mid) ret+=query(u->lc,l,mid,x,y);
- return ret;
- }
- inline int cmp(int x,int y) {
- return tid[x]<tid[y];
- }
- inline int lca(int x,int y) {
- while (ga[x]!=ga[y]) {
- if (deep[ga[x]]<deep[ga[y]])
- swap(x,y);
- x=fat[ga[x]];
- }
- if (deep[x]<deep[y]) return x;
- return y;
- }
- inline int query(int x,int y) {
- int ret=0;
- while (ga[x]!=ga[y]) {
- if (deep[ga[x]]<deep[ga[y]])
- swap(x,y);
- ret+=query(root,1,m,tid[ga[x]],tid[x]);
- update(root,1,m,tid[ga[x]],tid[x]);
- x=fat[ga[x]];
- }
- if (deep[x]>deep[y]) swap(x,y);
- if (tid[x]<=tid[y])
- ret+=query(root,1,m,tid[x],tid[y]),
- update(root,1,m,tid[x],tid[y]);
- return ret;
- }
- int main (int argc, char const* argv[]){
- int T=read();
- while (T--){
- memset(g,0,sizeof g);
- g[0].Clear();
- g[1].Clear();
- memset(cut,0,sizeof cut);
- memset(ncut,0,sizeof ncut);
- memset(dfn,0,sizeof dfn);
- memset(heavy,0,sizeof heavy);
- tcnt=tree;
- bcc_cnt=0;
- dfx=0,idx=0;
- n=read(),m=read();
- register int i,j;
- for (i=1;i<=m;++i) {
- int x=read(),y=read();
- g[0].push(x,y);
- }
- g[0].tarjan();
- int s=bcc_cnt;
- for (i=1;i<=n;++i)
- if (cut[i])
- ++s,cut[i]=s,ncut[cut[i]]=1;
- for (i=1;i<=bcc_cnt;++i) {
- for (j=0;j<bcc[i].size();++j)
- if (cut[bcc[i][j]])
- g[1].push(i,cut[bcc[i][j]]);
- else bel[bcc[i][j]]=i;
- }
- g[1].dfs();
- build(root,1,s);
- m=s;
- fina=tcnt;
- int Q=read(),tmp;
- int ans=0;
- while (Q--) {
- root=tree;
- tcnt=fina;
- s=read();
- for (i=1;i<=s;++i) {
- pos[i]=read();
- if (cut[pos[i]]) pos[i]=cut[pos[i]],update(root,1,m,tid[pos[i]],tid[pos[i]]);
- else pos[i]=bel[pos[i]];
- }
- sort(pos+1,pos+s+1,cmp);
- tmp=pos[1];
- ans=0;
- for (i=2;i<=s;++i) {
- ans+=query(tmp,pos[i]);
- }
- printf("%d\n",ans);
- }
- }
- return 0;
- }
「SDOI 2018」战略游戏的更多相关文章
- Solution -「SDOI 2018」「洛谷 P4606」战略游戏
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的无向连通图,\(q\) 次询问,每次给出一个点集 \(s\),求至少在原图中删去多 ...
- 「SDOI 2018」反回文串
题目大意: 求字符集大小为$k$长度为$n$的经循环移位后为回文串的数量. 题解: 这题是D1里最神的吧 考虑一个长度为$n$回文串,将其循环移位后所有的串都是满足要求的串. 但是显然这样计算会算重. ...
- 「TJOI 2018」教科书般的亵渎
「TJOI 2018」教科书般的亵渎 题目描述 小豆喜欢玩游戏,现在他在玩一个游戏遇到这样的场面,每个怪的血量为 \(a_i\) ,且每个怪物血量均不相同, 小豆手里有无限张"亵渎" ...
- LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)
写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...
- Loj #2494. 「AHOI / HNOI2018」寻宝游戏
Loj #2494. 「AHOI / HNOI2018」寻宝游戏 题目描述 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得 ...
- LOJ #2802. 「CCC 2018」平衡树(整除分块 + dp)
题面 LOJ #2802. 「CCC 2018」平衡树 题面有点难看...请认真阅读理解题意. 转化后就是,给你一个数 \(N\) ,每次选择一个 \(k \in [2, N]\) 将 \(N\) 变 ...
- LOJ #2541. 「PKUWC 2018」猎人杀(容斥 , 期望dp , NTT优化)
题意 LOJ #2541. 「PKUWC 2018」猎人杀 题解 一道及其巧妙的题 , 参考了一下这位大佬的博客 ... 令 \(\displaystyle A = \sum_{i=1}^{n} w_ ...
- LOJ #2540. 「PKUWC 2018」随机算法(概率dp)
题意 LOJ #2540. 「PKUWC 2018」随机算法 题解 朴素的就是 \(O(n3^n)\) dp 写了一下有 \(50pts\) ... 大概就是每个点有三个状态 , 考虑了但不在独立集中 ...
- LOJ #2538. 「PKUWC 2018」Slay the Spire (期望dp)
Update on 1.5 学了 zhou888 的写法,真是又短又快. 并且空间是 \(O(n)\) 的,速度十分优秀. 题意 LOJ #2538. 「PKUWC 2018」Slay the Spi ...
随机推荐
- [Domino]Java访问Domino必需配置的服务器设置
应用场景 我们需要通过Java远程访问IBM Lotus Domino R6和R5服务器,从中获取用户邮箱的邮件信息等关键数据.我们不需要提供每一个用户密码以及ID文件. 我们的具体做法是,通过Dom ...
- subclipse下svn: E200015: authentication cancelled问题的解决
今天要把新建的一个项目要share到一个Ubuntu下SVN服务上,总是让我不断的重复输入密码,实在是太要命了,点取消就报错如标题,Google了一下,最后在后面参考那篇帖子的启发下,到SVN配置里面 ...
- Ocelot中文文档-中间件注入和重写
警告!请谨慎使用. 如果您在中间件管道中看到任何异常或奇怪的行为,并且正在使用以下任何一种行为.删除它们,然后重试! 当在Startup.cs中配置Ocelot的时候,可以添加或覆盖中间件.如下所示: ...
- Ext Js Sencha Cmd 命令 打包charts
先进入charts包的目录下 cd D:\开发文档API\ext--gpl\packages\charts 在执行打包命令 sencha package build
- mybatis源码解读(三)——数据源的配置
在mybatis-configuration.xml 文件中,我们进行了如下的配置: <!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境常用: ...
- (三)SpringBoot基础篇- 持久层,jdbcTemplate和JpaRespository
一.介绍 SpringBoot框架为使用SQL数据库提供了广泛的支持,从使用JdbcTemplate的直接JDBC访问到完整的"对象关系映射"技术(如Hibernate).Spri ...
- 魔咒,90%未学满三个月Python编程的朋友都会出错!
Python语言虽然优美,简洁和强大,但是也有很多坑,一不小心就会掉进去.我学Python的时候也遇到过,今天总结一下,希望对大家能有收获! Python的默认参数就被创建 一次,而不是每次调用函数的 ...
- Linux(二十一)Shell编程
21.1 为什么要学习Shell编程 (1)Linux运维工程师在进行服务器集群管理时,需要编写Shell程序来进行服务器管理. (2)对于JavaEE和Python程序员来说,工作的需要,你的老大会 ...
- 网络-tcp
1.TCP:面向连接可靠的传输协议,全拼:Transmission Control Protocol 2.UDP:用户数据报协议 全拼:User Datagram protocol 不是面向连接的 ...
- python2.7 的中文编码处理,解决UnicodeEncodeError: 'ascii' codec can't encode character 问题
最近业务中需要用 Python 写一些脚本.尽管脚本的交互只是命令行 + 日志输出,但是为了让界面友好些,我还是决定用中文输出日志信息. 很快,我就遇到了异常: UnicodeEncodeError: ...