zoukankan      html  css  js  c++  java
  • 省选模拟(66~75)

    省选模拟66

    1.有限空间跳跃理论

    (FWT)
    给定一个无向图,要求给每条边定向后成为有向无环图,求方案
    考虑那个(dp)

    [dp[S]=sum_{Win S}(-1)^{|W|-1}dp[S-W] ]

    发现就是一个子集卷积的形式,所以开第二维再卷积就好了

    省选模拟67

    1.链

    模拟
    发现如果度数都小于3就可以根据有无环出答案
    否则假如第一个度数等于3的点为(x),那么为了使(x)最后度数小于3,最终消掉的点就只能是(x)或它相邻的3个点这四种选择
    所以把去掉这4个点的图分别建出来就好了

    省选模拟68

    1.Line

    二维数点
    (n)条直线,求在((x1,y1,x2,y2))这个矩形内至少一个交点的对数
    如果把矩形的四条边顺时针展开成一条线段,那么一条直线截线段必然会截出一个区间
    考虑到两直线相交等价于区间相交,即对于((l1,r1),(l2,r2))满足(l2in[l1,r1]&&r2>r1)
    如果按(r)升序,就可以扫描线(r),在线段树上单点查询此时左端点为(l)的答案
    扫描完这个(r)后呢,它可以为(lin[l,r])的贡献一份答案,因此再来一个区间+1就可以更新答案了

    省选模拟69

    2.没有上司的舞会

    在线,每次加入一个点,求树的最大独立集
    (LCT+DDP)

    #include<cstdio>
    #include<iostream>
    #define ll long long
    using namespace std;
    const int N=3e5+50;
    const int inf=0x3f3f3f3f;
    inline int rd(register int x=0,register char ch=getchar(),register int f=0){
    	while(ch<'0'||ch>'9') f=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    	return f?-x:x;
    }
    struct Matrix{
    	int a[2][2];
    	friend Matrix operator * (Matrix a,Matrix b){
    		Matrix c;
    		for(int i=0;i<2;++i) for(int j=0;j<2;++j) c.a[i][j]=max(a.a[i][0]+b.a[0][j],a.a[i][1]+b.a[1][j]);
    		return c;
    	}
    }g[N];
    int v[N][2];
    void output(Matrix *a){
    	for(int i=0;i<2;++i) for(int j=0;j<2;++j) printf("%lld ",a->a[i][j]);puts("");
    }
    namespace LCT{
    	int fa[N],ch[N][2];
    	bool nroot(int x){return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
    	bool get(int x){return ch[fa[x]][1]==x;}
    	void pushup(int x){
    		g[x]=(Matrix){v[x][0],v[x][1],v[x][0],-inf};
    		if(ch[x][1]) g[x]=g[ch[x][1]]*g[x];
    		if(ch[x][0]) g[x]=g[x]*g[ch[x][0]];
    	}
    	void rotate(int x){
    		int k=get(x),prt=fa[x],gr=fa[prt];
    		if(nroot(prt)) ch[gr][get(prt)]=x;fa[x]=gr;
    		ch[prt][k]=ch[x][k^1];if(ch[x][k^1]) fa[ch[x][k^1]]=prt;
    		ch[x][k^1]=prt; fa[prt]=x;
    		pushup(prt); pushup(x);
    	}
    	void splay(int x){
    		for(;nroot(x);rotate(x)) if(nroot(fa[x])) rotate(get(x)==get(fa[x])?fa[x]:x);
    	}
    	void access(int x){
    		for(int y=0;x;y=x,x=fa[x]){
    			splay(x);
    			if(ch[x][1]) v[x][0]+=max(g[ch[x][1]].a[0][0],g[ch[x][1]].a[0][1]),v[x][1]+=g[ch[x][1]].a[0][0];
    			if(y) v[x][0]-=max(g[y].a[0][0],g[y].a[0][1]),v[x][1]-=g[y].a[0][0];
    			ch[x][1]=y; pushup(x);
    			
    		}
    	}
    }
    using namespace LCT;
    int n,typ,lastans;
    int main(){
    	//freopen("text.in","r",stdin);
    	//freopen("a.out","w",stdout);
    	n=rd()+1,typ=rd(); v[1][1]=1; pushup(1);
    	for(int i=2;i<=n;++i){
    		fa[i]=(rd()^(typ*lastans))+1; access(i); splay(i); v[i][1]=1; pushup(i);
    		printf("%d
    ",lastans=max(g[i].a[0][0],g[i].a[0][1]));
    		//for(int j=1;j<=i;++j) printf("%d %d
    ",v[j][0],v[j][1]);
    	}
    }
    

    排列问题

    共有(m)个球分为(n)种颜色每种球有(a_i)个,求把这些球排列使得恰好有(k)对球相邻的方案数

    省选模拟70

    1.小Y增员操直播群

    若干个点合并成1个集合,大集合点向小集合点连边,现在给定连边方案,问最小合并次数

    2.小J真爱粉交流群

    两人博弈,轮流操作,在网格图内,小J每次可以(放置任意个)在上下相邻的两个点放墙,但不能让大墩与最后一行不连通
    大墩从第一行出发,最后权值为所有格子的权值和(重复计算),大墩想最小,小J想最大,问最小答案

    3.青青草原播种计划

    Q次操作,要求支持
    1.给u一个权值为v的种子
    2.收取u一个权值为v的种子(没有就不收)
    3.将u的种子全部转移给v
    4.询问u当前不可能播种出的最小种子权值,不可能播种出的子草原的最小绿植
    5.回到某个询问时查询当时的答案
    强制在线
    可持久化权值线段树
    当前不可能播种出的最小种子权值就是mex,用权值线段树自带维护
    不可能播种出的子草原的最小绿植有套路
    考虑维护小于等于某个值的权值和(sum)
    那么(sum[u]>=u),说明(ans>=sum[u]+1)
    因为对于(ans),(ans=min(sum[u]==u)+1)
    说的很费劲

  • 相关阅读:
    mvc页面中,显示自定义时间格式
    时间格式字符串中,大小写字母的解释
    subversion SVN global ignore pattern
    .net项目svn项目管理文件清单
    nopcommerce插件相关
    vs2013执行Add-Migration出现的问题
    jquery为多个元素添加事件
    在JavaScript中创建命名空间的几种写法
    Python 创建XML 的三种方式
    Python 对网页操作的方法, urllib ;requests
  • 原文地址:https://www.cnblogs.com/hzoi2018-xuefeng/p/12677544.html
Copyright © 2011-2022 走看看