寻宝游戏

毒瘤题。

估计考试只会前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. LeetCode【83. 删除排序链表中的重复元素】

    我最开始的程序是 但是结果

  2. HTML span标签:用来组合文档中的行内元素

    在DIV+CSS切图布局重构技术中,除了常常使用div标签外也常常使用span标签布局,通常也可以通过对span标签对象设置不同样式实现我们要的美化效果.这里主机吧主要讲的是span标签的定义和用法. ...

  3. 用户名、密码等15个常用的js正则表达式

    本文收集整理了15个常用的javaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IPv4地址. 十六进制颜色. 日期. Q ...

  4. 【亲测】解决虚拟机CentOS7联网ping不通相关问题(通俗易懂)

    对于是使用windows操作系统的小伙伴来说(mac用户忽略),要学习一些技术可能需要使用Linux系统,自然就需要使用虚拟机安装Linux,当然现在很多主流的学习网站上的教程都会提供老师配置好的虚拟 ...

  5. junit 基础使用

    junit百度百科: JUnit是一个Java语言的单元测试框架.它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个. JU ...

  6. TCARS: Time- and Community-Aware Recommendation System(时间感知和社区感知推荐系统)

    随着用户在物品上产生了大量行为,推荐系统成为了线上系统的重要组成部分.推荐系统算法使用用户对物品的行为信息以及上下文数据为每个用户推荐一组物品.算法根据用户之间及物品之间的相似度建立.本文介绍了一个基 ...

  7. idea导入项目

    1. 2.导入项目 3.右键项目选择web 4.编辑添加tomcat 5.添加jar.包 6. 7.右键put into 8.安装tomcat 9.引入tomcat 10.把项目布署到tomcat

  8. 学习node.js 第1篇 介绍nodejs

    Node.js是什么? Node.js是建立在谷歌Chrome的JavaScript引擎(V8引擎)的Web应用程序框架. 它的最新版本是:v0.12.7(在编写本教程时的版本).Node.js在官方 ...

  9. laravel PHPExcel 使用小结

    最近需求要用到PHPExcel,laravel框架中有相应的组件https://github.com/Maatwebsite/Laravel-Excel,我用的是2.1的(3.0文档不详细而且坑似乎也 ...

  10. 从一个简单的约束看规范性的SQL脚本对数据库运维的影响

    之前提到了约束的一些特点,看起来也没什么大不了的问题,http://www.cnblogs.com/wy123/p/7350265.html以下以实际生产运维中遇到的一个问题来说明规范的重要性. 如下 ...