zoukankan      html  css  js  c++  java
  • 【BZOJ3563】DZY Loves Chinese(挖坟:长达20个月的坑)

    点此看题面

    大致题意: 一张无向图。每次询问给出一行,第一个数(k),以及接下来(k)个数表示边的编号,要求回答删去这(k)条边后图是否联通。强制在线,每次询问的(k)及其后(k)个数全都要异或上之前回答连通的次数。

    前言

    挖坟祭。。。

    【洛谷5236】【模板】静态仙人掌(圆方树板子)这道题之后又一次写掉一道咕了超过一年的题目。

    然而上面那题还只是咕了(14)个月,这道题居然咕了(20)个月。。。

    为什么会突然想到写这道题呢?

    这则是因为做了这道题:【BZOJ3214】[ZJOI2013] 丽洁体(毒瘤字符串读入+动态规划水题)。然后我就自认为现在应该能更好地处理此类和读入有关的问题。

    我先找到了原先的代码,然后发现以前的码风和现在截然不同(原先那些变量名定义得超长无比,而且那时似乎还处于我不压行与压行的过渡时期,因此十分清奇),于是恶改了一阵码风。

    好不容易改完了码风,然后。。。

    就过了?!

    又仔细去看了一遍发现原来的代码甚至连样例都没过!(样例都没过我居然敢交,我真佩服过去自己的胆量。。。)

    接下来好好研读了一遍原先的代码,发现有一个写得十分丑陋怪异的地方很智障地写挂了,而我改码风时看它不顺眼就把它拍扁+重构了一遍,于是就歪打正着地对了。。。

    乱搞

    此题是道乱搞题,正经做法请见另一道题:【BZOJ3569】DZY Loves Chinese II

    好好看看题目中给出的强制在线方式, 就会发现它居然把每次询问的(k)也异或了!

    于是我们就会有一个乱搞的想法:每次读入它给出的(k'),然后求出实际数的个数(k),就会发现(k' xor k)即为之前回答连通的个数,只要差分一下就能求出上次的答案!

    然后我们只要(O(n))并查集暴力搞一下最后一个询问,于是这道题就做完了。。。

    具体实现详见代码。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define M 500000
    #define LL long long
    #define INF 1e9
    using namespace std;
    int n,m,a[20],fa[N+5],del[M+5];struct edge {int x,y,nxt,pos;}e[M+5];
    I bool read(int& x)//读入,实际上类似于读优
    {
    	#define D isdigit(c)
    	static char c=getchar();W(!D) {if(c=='
    '||c==EOF) return c=getchar(),0;c=getchar();}//如果读到回车或终止符
    	x=0;W(D) x=(x<<3)+(x<<1)+(c&15),c=getchar();return 1;
    }
    I int getfa(CI x) {return fa[x]^x?fa[x]=getfa(fa[x]):x;}
    int main()
    {
    	RI Qt,i,x,y,s,t,ans=0,f=1,fx,fy;
    	for(scanf("%d%d",&n,&m),i=1;i<=m;++i) scanf("%d%d",&x,&y),e[i].x=x,e[i].y=y;//读入边
    	for(scanf("%d",&Qt);Qt;--Qt)//处理询问
    	{
    		W(!read(s));t=0;W(read(a[++t]));--t;//读入这一行的数,注意个数减1,因为最后一个读失败的数不能算在内
    		f?f=0:(s^t^ans?(puts("Connected"),ans=s^t):puts("Disconnected"));
    		//若当前不是第一个询问,如果回答连通次数与之前不同,说明上次回答连通,否则上次回答不连通
    	}
    	//接下来是暴力
    	for(i=1;i<=t;++i) del[a[i]^ans]=1;for(i=1;i<=n;++i) fa[i]=i;//标记被删的边,预处理并查集
    	for(i=1;i<=m;++i) !del[i]&&(fx=getfa(e[i].x))^(fy=getfa(e[i].y))&&(fa[fy]=fx);//对于没被删的边,合并连通块
    	for(getfa(1),i=2;i<=n;++i) if(getfa(i)^fa[1]) return puts("Disconnected"),0;//判断是否连通
    	return puts("Connected"),0;
    }
    
  • 相关阅读:
    病毒
    最短母串
    单词
    Censoring
    玄武密码
    Keywords Search
    聚会
    异象石
    暗的连锁
    pat 1048. Find Coins (25)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ3563.html
Copyright © 2011-2022 走看看