寻宝游戏

毒瘤题。

估计考试只会前30pts30pts30pts暴力然后果断走人。

正解是考虑到一个数&1\&1&1和∣0|0∣0都没有变化,&0\&0&0会强制变成000,∣1|1∣1会强制变成111,于是如果结果是111说明最后一个出现的∣1|1∣1在最后一个出现的&0\&0&0的后面,这样我们将所有的操作集合拿来搞成一个010101串并把所有010101串反向之后就可以求出可行范围然后得出答案了。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<1)+(ans<<3)+(ch^48),ch=getchar();
	return ans;
}
const int mod=1e9+7,N=5005;
int n,m,q,Bit[N],sum[N],c[2],rk[N],lastrk[N],l,r;
char s[N];
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline void update(int&a,const int&b){a=add(a,b);}
inline void init(){
	for(ri i=Bit[0]=1;i<=n;++i)Bit[i]=(Bit[i-1]<<1)%mod;
    for(ri i=1;i<=m;++i)rk[i]=i;
}
inline void Sort(){
    for(ri i=c[0]=c[1]=0;i<n;++i,c[0]=c[1]=0){
        scanf("%s",s+1);
        for(ri j=1;j<=m;++j)++c[s[j]^48],update(sum[j],(s[j]^48)*Bit[i]);
        c[1]+=c[0];
        for(ri j=m;j;--j)lastrk[c[s[rk[j]]^48]--]=rk[j];
		swap(lastrk,rk);
    }
}
int main(){
    n=read(),m=read(),q=read(),init(),Sort();
	while(q--){
        scanf("%s",s+1),l=0,r=m+1;
        for(ri i=1;i<=m;++i)if(s[rk[i]]^48){r=i;break;}
        for(ri i=m;i;--i)if(!(s[rk[i]]^48)){l=i;break;}
        l>=r?cout<<0<<'\n':cout<<(dec(r>m?Bit[n]:sum[rk[r]],sum[rk[l]]))<<'\n';
    }
	return 0;
}

转盘

考虑时间倒流转化问题:

想象成从TTT时刻开始每个时刻可以倒着走一步或者停住,每个物品有一个消失时间,要在所有物品消失之前经过它们。

为了方便我们断环为链

假设是从iii开始倒退(n≤i&lt;2n)(n\le i&lt;2n)(n≤i<2n),则有T−(i−j)≥tj⇒T≥(tj−j)+i⇒Tmin=max⁡{Tj−j}+iT-(i-j)\ge t_j\Rightarrow T\ge(t_j-j)+i\Rightarrow T_{min}=\max\{T_j-j\}+iT−(i−j)≥tj​⇒T≥(tj​−j)+i⇒Tmin​=max{Tj​−j}+i。

令ai=ti−ia_i=t_i-iai​=ti​−i

那么Ans=minn≤i&lt;2n{maxi−n&lt;j≤i{aj}+i}Ans=min_{n\le i&lt;2n}\{max_{i-n&lt;j\le i}\{a_j\}+i\}Ans=minn≤i<2n​{maxi−n<j≤i​{aj​}+i}

因为ai&gt;ai+n,i≤na_i&gt;a_{i+n},i\le nai​>ai+n​,i≤n

所以Ans=min1≤i≤n{maxi≤j≤2n{aj}+i}+n−1Ans=min_{1\le i\le n}\{max_{i\le j\le 2n}\{a_j\}+i\}+n-1Ans=min1≤i≤n​{maxi≤j≤2n​{aj​}+i}+n−1

然后发现就是唯一一个后缀maxmaxmax的minminmin,这个可以用线段树维护单调栈实现。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<1)+(ans<<3)+(ch^48),ch=getchar();
	return ans;
}
const int N=1e5+5,inf=0x3f3f3f3f;
int n,m,lastans,a[N<<1],type;
namespace SGT{
	#define lc (p<<1)
	#define rc (p<<1|1)
	#define mid (T[p].l+T[p].r>>1)
	struct Node{int l,r,val,mx;}T[N<<3];
	inline int query(int p,int lim,int v){
		if(T[p].l==T[p].r)return min(T[p].l==lim?inf:T[p].l+1+v,T[p].l+max(v,T[p].mx));
		if(v>=T[rc].mx)return query(lc,lim,v);
		return min(T[p].val,query(rc,lim,v));
	}
	inline void pushup(int p){T[p].mx=max(T[lc].mx,T[rc].mx),T[p].val=query(lc,mid,T[rc].mx);}
	inline void build(int p,int l,int r){
		T[p].l=l,T[p].r=r;
		if(l==r){T[p].mx=a[l];return;}
		build(lc,l,mid),build(rc,mid+1,r),pushup(p);
	}
	inline void update(int p,int k,int v){
		if(T[p].l==T[p].r){T[p].mx=v;return;}
		update(k<=mid?lc:rc,k,v),pushup(p);
	}
	#undef lc
	#undef rc
	#undef mid
}
int main(){
  	n=read(),m=read(),type=read();
  	for(ri i=1;i<=n;++i)a[i]=read()-i,a[i+n]=a[i]-n;
  	SGT::build(1,1,n<<1);
  	cout<<(lastans=SGT::T[1].val+n-1)<<'\n';
  	for(ri x,y;m;--m){
  		x=read()^(type*lastans),y=read()^(type*lastans);
  		SGT::update(1,x,y-x),SGT::update(1,x+n,y-x-n);
		cout<<(lastans=SGT::T[1].val+n-1)<<'\n';
  	}
	return 0;
}

毒瘤

枚举边的状态+树形dpdpdp这种暴力757575应该都是一眼会吧。

但这样会TLETLETLE掉最后几个点 出题人毒瘤

然后需要建出这棵树的虚树来优化每次dpdpdp的时间。

然后就没了。

代码:

#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<1)+(ans<<3)+(ch^48),ch=getchar();
    return ans;
}
typedef pair<int,int> pii;
typedef long long ll;
const int N=1e5+5,mod=998244353;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
int P[N][2],n,m,ans=0,f[N][2],siz[N],tot=0,dfn[N];
vector<int>e[N];
vector<pii>G;
bool vis[N],key[N],ban[N][2];
void Dfs(int p,int fa){
    dfn[p]=++tot;
    for(ri i=0,v;i<e[p].size();++i){
        if((v=e[p][i])==fa)continue;
		if(dfn[v]){key[p]=1;if(dfn[p]<dfn[v])G.push_back(pii(p,v));continue;}
        else Dfs(v,p),siz[p]+=siz[v];
    }
    key[p]|=siz[p]>=2;
	siz[p]=siz[p]||key[p];
}
struct Coef{
	int x,y;
	Coef(int _x=0,int _y=0):x(_x),y(_y){}
	friend inline Coef operator+(const Coef&a,const Coef&b){return Coef(add(a.x,b.x),add(a.y,b.y));}
	friend inline Coef operator*(const Coef&a,const int&b){return Coef(mul(a.x,b),mul(a.y,b));}
}k[N][2];
struct Node{int v;Coef a,b;};
vector<Node>E[N];
inline int Build(int p){
	P[p][0]=P[p][1]=vis[p]=1;
	int ret=0;
	for(ri w,i=0,v;i<e[p].size();++i){
		if(vis[v=e[p][i]])continue;
		w=Build(v);
		if(!w)P[p][1]=mul(P[p][1],P[v][0]),P[p][0]=mul(P[p][0],add(P[v][0],P[v][1]));
		else if(key[p])E[p].push_back((Node){w,k[v][0]+k[v][1],k[v][0]});
		else k[p][0]=k[v][0]+k[v][1],k[p][1]=k[v][0],ret=w;
	}
	if(key[p])k[p][0]=Coef(1,0),k[p][1]=Coef(0,1),ret=p;
	else k[p][0]=k[p][0]*P[p][0],k[p][1]=k[p][1]*P[p][1];
	return ret;
}
inline void solve(int p){
	f[p][0]=ban[p][0]?0:P[p][0];
	f[p][1]=ban[p][1]?0:P[p][1];
	for(ri i=0,v;i<E[p].size();++i){
		solve((v=E[p][i].v));
		f[p][0]=mul(f[p][0],add(mul(E[p][i].a.x,f[v][0]),mul(E[p][i].a.y,f[v][1])));
		f[p][1]=mul(f[p][1],add(mul(E[p][i].b.x,f[v][0]),mul(E[p][i].b.y,f[v][1])));
	}
}
inline void init(int sta){
    for(ri i=0,x,y,tmp;i<G.size();++i){
        tmp=(sta>>i)&1,x=G[i].fi,y=G[i].se;
        if(!tmp)ban[x][1]=1;
        else ban[x][0]=ban[y][1]=1;
    }
    solve(1),ans=add(ans,add(f[1][0],f[1][1]));
    for(ri i=0,x,y,tmp;i<G.size();++i){
        tmp=(sta>>i)&1,x=G[i].fi,y=G[i].se;
        if(!tmp)ban[x][1]=0;
        else ban[x][0]=ban[y][1]=0;
    }
}
int main(){
  	n=read(),m=read();
  	for(ri i=1,u,v;i<=m;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
	Dfs(1,0),key[1]=1,Build(1);
  	for(ri sta=0,up=1<<G.size();sta<up;++sta)init(sta);
  	cout<<ans;
    return 0;
}

游戏

对于两个可以不能相通的块,如果钥匙在左边,那么可能可以从左到右但并不能从右到左,我们对于这种情况建一条有向边,然后动态维护一个拓扑排序即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=1e6+5;
int n,m,q,goa[N],l[N],r[N],mp[N],du[N],tot=0,x,y;
vector<int>e[N];
inline void add(const int&u,const int&v){e[u].push_back(v),++du[v];}
inline void extend(int i){
	static int t1,t2;
	while(1){
        t1=l[i]^1,t2=r[i]^n;
        if(t1)(!goa[l[i]-1])||(goa[l[i]-1]>=l[i]&&goa[l[i]-1]<=r[i])?l[i]=l[mp[l[i]-1]]:t1=0;
        if(t2)(!goa[r[i]])||(goa[r[i]]>=l[i]&&goa[r[i]]<=r[i])?r[i]=r[mp[r[i]+1]]:t2=0;
        if(!(t1+t2))break;
    }
}
inline void topsort(){
	static int q[N],hd,tl;
	hd=1,tl=0;
    for(ri i=1;i<=n;i++)if(mp[i]==i&&!du[i])q[++tl]=i;
    while(hd<=tl){
        int p=q[hd++];
		extend(p);
		for(ri i=0,v;i<e[p].size();++i)if(!(--du[v=e[p][i]]))q[++tl]=v;
    }
}
int main(){
    n=read(),m=read(),q=read();
    for(ri i=1;i<=n;i++)mp[i]=l[i]=r[i]=i;
    while(m--)x=read(),goa[x]=read();
    for(ri i=1;i<=n;i++)if(!goa[i])mp[i+1]=mp[i];else goa[i]<=i?add(mp[i+1],mp[i]):add(mp[i],mp[i+1]);
    for(ri i=1;i<=n;i++)l[mp[i]]=min(l[mp[i]],l[i]),r[mp[i]]=max(r[mp[i]],r[i]);
    topsort();
    for(ri i=1;i<=n;i++)l[i]=l[mp[i]],r[i]=r[mp[i]];
    while(q--)x=read(),y=read(),puts(l[x]<=y&&y<=r[x]?"YES":"NO");
    return 0;
}

排列

考虑按照题意建边建出来是一棵外向树。

然后显然应该按某一种拓扑序来形成序列(注意这个时候要判环来看是否合法)

这个东西可以用并查集+堆来搞一下,比较的依据是一个连通块的平均权值。

代码:

#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<1)+(ans<<3)+(ch^48),ch=getchar();
    return ans;
}
const int N=5e5+5;
typedef long long ll;
typedef pair<long double,int> pii;
int n,m,siz[N],fa[N],anc[N];
ll w[N],ans=0;
inline int find(const int&x){return x^anc[x]?anc[x]=find(anc[x]):x;}
struct In_Out_queue{
	priority_queue<pii,vector<pii>,greater<pii> >a,b;
	inline void push(const pii&x){a.push(x);}
	inline void del(const pii&x){b.push(x);}
	inline pii top(){while(b.size()&&a.top()==b.top())a.pop(),b.pop();return a.top();}
	inline void pop(){while(b.size()&&a.top()==b.top())a.pop(),b.pop();a.pop();}
}q;
int main(){
	n=read();
	for(ri i=0;i<=n;++i)anc[i]=i;
	for(ri i=1;i<=n;++i){
		fa[i]=read();
		if(anc[find(i)]^anc[find(fa[i])])anc[find(i)]=find(fa[i]);
		else return puts("-1"),0;
	}
	ll ans=0;
	anc[0]=0;
	for(ri i=1;i<=n;++i)ans+=(w[i]=read()),anc[i]=i,siz[i]=1,q.push(pii((long double)w[i],i));
	for(ri i=1;i<=n;++i){
		int x=q.top().se,y=find(fa[x]);
		q.pop();
		if(y)q.del(pii((long double)w[y]/siz[y],y));
		ans+=(ll)siz[y]*w[x],siz[y]+=siz[x],anc[x]=y,w[y]+=w[x];
		if(y)q.push(pii((long double)w[y]/siz[y],y));
	}
	cout<<ans;
    return 0;
}

道路

HNOI2018最水的一道没有之一没错就是它。 并不是反话

由于题目中给了深度保证,于是直接暴力三维树形dpdpdp就能过了。

记忆化搜索真的好写

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline int read(){
    int ans=0;
    bool f=1;
    char ch=getchar();
    while(!isdigit(ch))f^=ch=='-',ch=getchar();
    while(isdigit(ch))ans=(ans<<1)+(ans<<3)+(ch^48),ch=getchar();
    return f?ans:-ans;
}
const int N=20005;
ll a[N],b[N],c[N],f[N][45][45];
int son[N][2],n;
ll dfs(int p,int x,int y){
	if(p>=n)return c[p-n+1]*(a[p-n+1]+x)*(b[p-n+1]+y);
	if(f[p][x][y]^f[0][0][0])return f[p][x][y];
	return f[p][x][y]=min(dfs(son[p][0],x,y)+dfs(son[p][1],x,y+1),dfs(son[p][0],x+1,y)+dfs(son[p][1],x,y));
}
int main(){
	n=read();
	memset(f,127,sizeof(f));
	for(ri i=1,x,y;i<n;++i){
		x=read(),y=read();
		if(x<0)x=n-x-1;
		if(y<0)y=n-y-1;
		son[i][0]=x,son[i][1]=y;
	}
	for(ri i=1;i<=n;++i)a[i]=read(),b[i]=read(),c[i]=read();
	return cout<<dfs(1,0,0),0;
}

HNOI 2018 简要题解的更多相关文章

  1. JXOI 2018 简要题解

    目录 「JXOI2018」游戏 题意 题解 代码 「JXOI2018」守卫 题意 题解 代码 「JXOI2018」排序问题 题意 题解 代码 总结 「JXOI2018」游戏 题意 可怜公司有 \(n\ ...

  2. NOIP 2018 简要题解

    从这里开始 Day 1 Problem A 考虑贪心地选取极大非 0 段减少. 如果两次操作有交,并且不是包含关系,那么把其中一次操作的,但另一次没有操作的移过去,然后就变成了上面那个贪心了. Cod ...

  3. codechef February Challenge 2018 简要题解

    比赛链接:https://www.codechef.com/FEB18,题面和提交记录是公开的,这里就不再贴了 Chef And His Characters 模拟题 Chef And The Pat ...

  4. HNOI2019 简要题解

    HNOI 2019 简要题解 没想到自己竟也能有机会写下这篇题解呢. LOJ Luogu Day1T1 鱼 枚举\(AD\)两点后发现\(BC\)与\(EF\)相对独立,因此只需要计算合法的\(BC\ ...

  5. Tsinghua 2018 DSA PA2简要题解

    反正没时间写,先把简要题解(嘴巴A题)都给他写了记录一下. upd:任务倒是完成了,我也自闭了. CST2018 2-1 Meteorites: 乘法版的石子合并,堆 + 高精度. 写起来有点烦貌似. ...

  6. HNOI2018简要题解

    HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...

  7. CQOI2018简要题解

    CQOI2018简要题解 D1T1 破解 D-H 协议 题意 Diffie-Hellman 密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码)的情况下,通过不安全的信 ...

  8. A · F · O —— JLOI2018翻车记(附Day1简要题解)

    JLOI2018翻车记 并不知道该怎么写... 算了还是按照标准剧情来吧 这应该是一篇写得非常差的流水账... 2018.04.04 Day -1 省选前在机房的最后一天. 压力并不是很大,毕竟联赛 ...

  9. Noip 2014酱油记+简要题解

    好吧,day2T1把d默认为1也是醉了,现在只能期待数据弱然后怒卡一等线吧QAQ Day0 第一次下午出发啊真是不错,才2小时左右就到了233,在车上把sao和fate补掉就到了= = 然后到宾馆之后 ...

随机推荐

  1. 初识docker-镜像

    前言: 以前学习docker 都是零零碎碎的,只知道用,有些莫名其妙的报错自己也没有思路去解决,所以基于一本专业的介绍docker的书籍,重新开启学习,该博客就记录下我自己的学习过程吧. 1.dock ...

  2. html/css/js-横向滚动条的实现

    在前端UI设计时,网页的制作很麻烦,深有感悟!碰到太多的不懂,或是第一次见,就要去网上找资料!横向滚动条就是我遇到麻烦中其中的一个,其实也 很简单,只是在几次项目中都用到了这个横向滚动条所以就拿出来说 ...

  3. Java访问Phoenix连接

    两种方法,一种是直接使用jdbc连接,一种是使用spring连接. jdbc连接和访问oracle步骤相同: ///////////// 测试Phoenix连接 /////////////// Str ...

  4. ETL讲解(很详细!!!)

    ETL讲解(很详细!!!) ETL是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,目的是将企业中的分散.零乱.标准不统一的数据整合到一起,为企业的决策提供分析依据. ETL是BI项目重要 ...

  5. Android SDK + Appium 环境搭建

    一.JDK 安装 说明:JDK是包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具,所以必须最先安装. 链接: https://pan.baidu.com/s/1NfNK_K7vukF ...

  6. python大法好——递归、内置函数、函数进阶

    1.递归(自己干自己) def fun(n): n=n/2 print(n) if(n>2) fun(n) #函数调用 fun(10) 结果是5 2 1 0 递归的执行过程:递归执行到最里面一层 ...

  7. mybatis sql参考

    参考mybatis sql: <select id="xxx" resultType="com.xxxx.xxx.vo.xx.xx" parameterT ...

  8. [Redis]Redis高级特性的配置及使用

    ---------------------------------------------------------------------------- [Redis安全性] 一 . 默认我们进入Re ...

  9. Delphi TXLSReadWriteII 导出EXCEL

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  10. Java获取工程目录

    背景:程序执行时,会涉及到去读取配置文件等操作,那就需要了解怎么获得文件路径   Java目录映射关系 说明一点:在Java代码执行时,会将编译生成的classes文件,以及配置文件等信息生成到tar ...