寻宝游戏

毒瘤题。

估计考试只会前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. 利用Kettle 从Excel中抽取数据写入SQLite

    SQLite作为一种数据库可以配置为Kettle的数据输入和输出,这个例子是从Excel中抽取数据然后写入到SQLite中 配置测试并成功后如下 下面是配置步骤: Excel输入配置 sqlite配置 ...

  2. python数据格式化之pprint

    python数据格式化之pprint 2017年06月17日 13:56:33 阅读数:2291 简介 pprint模块 提供了打印出任何Python数据结构类和方法. 模块方法: 1.class p ...

  3. 当一个HTML元素需要添加mouseon、mouseout与click事件,或者mouserenter、mouseleave和click事件时,click事件无法触发

    当一个HTML元素需要添加mouseon.mouseout与click事件,或者mouserenter.mouseleave和click事件时,click事件无法触发 针对上述问题,我遇到的有两种情况 ...

  4. SQLServer 清空某个库所有表

    select @n=1 insert #temp(tablename) SELECT distinct sobjects.name FROM sysobjects sobjects WHERE sob ...

  5. Linux背背背(2)

    目录: 1.简单命令 2.目录切换命令 3.扩展命令 简单命令 ls 语法1:#ls [路径]            表示列出指定路径下的文件夹和文件的名字,如果路径没有指定则列出当前路径下的 语法2 ...

  6. oracle的权限和角色

    1 介绍  这一部分我们主要看看oracle是如何管理权限和角色的,权限和角色的区别在哪里. 当刚刚建立用户时,用户没有任何权限,也不能执行任何操作.如果要执行某种特定的数据库操作,则必须为其授予系统 ...

  7. (转)适用微信小程序的table表格(带隔行变色)

    原文地址 table.wxml <view class="table"> <view class="tr bg-w"> <view ...

  8. 【Linux】【Chrome】安装Chrome浏览器的攻略

    https://blog.csdn.net/chenlix/article/details/72526205 1.切换到root: su - 或者 sudo -i 2.下载新的软件源定义: cd /e ...

  9. 如何正确实现 Java 中的 HashCode

    相等 和 Hash Code 从一般角度来看,Equality 是不错的,但是 hash code 更则具技巧性.如果我们在 hash code上多下点功夫,我们就能了解到 hash code 就是用 ...

  10. ansible 问题

    如下图,A服务器上用普通账号ansible有时就会报错,但有时却又正常,可以连接成功,用root账号执行ansible就完全没问题. 仅仅是这一台服务器有问题,其他都完全正常..ansible 文件删 ...