文章目录

传送门

GGG题手速慢了没有在比赛的时候码出来233,FFF题居然没想出来?

五道题滚粗。

先谈谈其他几道题。

A题

传送门 不小心看错题

直接看奇偶性构造答案。

如果是奇数就用一个3和几个2,不然就全部用2.

代码:

#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=105;
int n,a[N],f[N];
int main(){
	n=read(),f[0]=1;
	for(ri i=1;i<=n;++i){
		int x=read();
		if(x&1)cout<<1+(x-3)/2<<'\n';
		else cout<<x/2<<'\n';
	}
	return 0;
}

B题

传送门 明显送分

我们直接将所有字符串排序,看有没有所有字符都是一样的就行了。

代码:

#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=105;
char s[10005];
int t;
int main(){
	t=read();
	while(t--){
		scanf("%s",s+1);
		int n=strlen(s+1);
		sort(s+1,s+n+1);
		bool f=0;
		for(int i=1;i<n;++i)if(s[i]!=s[i+1]){f=1;break;}
		if(!f){puts("-1");continue;}
		for(ri i=1;i<=n;++i)cout<<s[i];
		puts("");
	}
	return 0;
}

C题

传送门 明显送分

按照题意模拟。

由于题目保证有合法方案,因此我们先保证aia_iai​最小,如果aia_iai​不合法就保证an−i+1a_{n-i+1}an−i+1​最大。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
inline ll read(){
	ll 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=2e5+5;
int n;
ll a[N],b[N];
int main(){
	n=read();
	for(ri i=1;i<=n/2;++i)b[i]=read();
	for(ri i=1;i<=n/2;++i){
		a[i]=a[i-1],a[n-i+1]=b[i]-a[i];
		if(a[n-i+1]>a[n-i+2]&&i!=1)a[n-i+1]=a[n-i+2],a[i]=b[i]-a[n-i+1];
	}
	for(ri i=1;i<=n;++i)cout<<a[i]<<' ';
	return 0;
}

D题

传送门 明显送分

题目要说的就是相邻两点奇偶性不同。

因此可以假设一号点为奇,先二分图染色看是否合法。

如果对于某个yyy个点的子图这时候编号为奇数的点有xxx个,那么这个子图的贡献就是2x+2y−x2^x+2^{y-x}2x+2y−x,最后乘起来就行了。

代码:

#include<bits/stdc++.h>
#define ri long long
#define int long long
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<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
const int N=3e5+5,mod=998244353;
int n,t,m,col[N],cnt=0,tot=0;
vector<int>e[N];
inline bool dfs(int p,int val){
	++cnt,col[p]=val;
	if(!val)++tot;
	for(ri i=0;i<e[p].size();++i){
		int v=e[p][i];
		if(~col[v]){
			if(col[v]==col[p])return false;
			continue;
		}
		if(!dfs(v,val^1))return false;
	}
	return true;
}
inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=(ll)a*a%mod)if(p&1)ret=(ll)ret*a%mod;return ret;}
signed main(){
	for(ri tt=read();tt;--tt){
		n=read(),m=read();
		for(ri i=1;i<=n;++i)e[i].clear(),col[i]=-1;
		for(ri i=1,u,v;i<=m;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
		ll ans=1;
		bool f=1;
		for(ri i=1;i<=n;++i){
			if(col[i]==-1){
				cnt=0,tot=0;
				if(!dfs(i,0)){
					f=false;
					break;
				}
				ans=(ll)ans*(ksm(2,tot)+ksm(2,cnt-tot))%mod;
			}
		}
		if(!f){puts("0");continue;}
		cout<<ans<<'\n';
	}
	return 0;
}

E题

传送门 有点烦人

把一个数iii在a,ba,ba,b数列中的下标ai,bia_i,b_iai​,bi​看成坐标,然后相当于就是一个二维数点问题了。

直接上cdqcdqcdq分治即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=2e5+5,M=2e5+5,K=2e5+5;
struct Pot{int x,y,z,t,id,f;}q[N<<3],tmp[N<<3];
struct Node{int x,y;}pos[N];
int n,s,k,m,m_,bit[M],ans[K],a[N],b[N];
inline int read(){
    int ans=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans*w;
}
inline int lowbit(int x){return x&-x;}
inline void update(int x,int v){for(int i=x;i<=n;i+=lowbit(i))bit[i]+=v;}
inline int query(int x){int ret=0;for(int i=x;i;i-=lowbit(i))ret+=bit[i];return ret;}
void solve(int l,int r){
    if(l==r)return;
    int mid=l+r>>1,pos1=l,pos2=mid+1;
    for(ri i=l;i<=r;++i){
        if(q[i].t<=mid&&!q[i].f)update(q[i].y,q[i].z);
        if(q[i].t>mid&&q[i].f)ans[q[i].id]+=q[i].z*query(q[i].y);
    }
    for(ri i=l;i<=r;++i)if(q[i].t<=mid&&!q[i].f)update(q[i].y,-q[i].z);
    for(ri i=l;i<=r;++i)
        if(q[i].t<=mid)tmp[pos1++]=q[i];
        else tmp[pos2++]=q[i];
    for(ri i=l;i<=r;++i)q[i]=tmp[i];
    solve(l,mid),solve(mid+1,r);
}
inline bool cmp(Pot a,Pot b){return a.x<b.x||(a.x==b.x&&a.y<b.y)||(a.x==b.x&&a.y==b.y&&a.f<b.f);}
int main(){
	n=read(),m=read(),k=0,m_=0;
	for(ri i=1;i<=n;++i)pos[a[i]=read()].x=i;
	for(ri i=1;i<=n;++i)pos[b[i]=read()].y=i;
	for(ri i=1;i<=n;++i)q[++k]=(Pot){pos[i].x,pos[i].y,1,k,m_,0};
	for(ri i=1,op,x1,x2,y1,y2;i<=m;++i){
		op=read();
		if(op==1){
			++m_,x1=read()-1,x2=read(),y1=read()-1,y2=read();
			q[++k]=(Pot){x1,y1,1,k,m_,1};
			q[++k]=(Pot){x1,y2,-1,k,m_,1};
			q[++k]=(Pot){x2,y1,-1,k,m_,1};
			q[++k]=(Pot){x2,y2,1,k,m_,1};
		}
		else{
			int x=read(),y=read();
			#define b1 pos[b[x]]
			#define b2 pos[b[y]]
			q[++k]=(Pot){b1.x,b1.y,-1,k,m_,0};
			q[++k]=(Pot){b2.x,b2.y,-1,k,m_,0};
			swap(b[x],b[y]),b1.y=x,b2.y=y;
			q[++k]=(Pot){b1.x,b1.y,1,k,m_,0};
			q[++k]=(Pot){b2.x,b2.y,1,k,m_,0};
		}
	}
	sort(q+1,q+k+1,cmp),solve(1,k);
	for(ri i=1;i<=m_;++i)cout<<ans[i],puts("");
}

F题

传送门 送分没拿

考虑dpdpdp。

fi,jf_{i,j}fi,j​表示当前在第iii个位置,第iii个位置放jjj的合法方案数。

显然可以从上一个位置的递推过来,然后判断是否需要扣去这连续kkk个都相同的方案数。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=1e5+5,K=105,mod=998244353;
inline int read(){
	int ans=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans*w;
}
int n,k,len,a[N],f[N][105],g[N],ans[N],cnt[N];
int main(){
	freopen("lx.in","r",stdin);
	n=read(),k=read(),len=read();
	for(ri i=1;i<=n;++i)a[i]=read();
	if(len<2)puts("0"),exit(0);
	g[0]=ans[0]=1;
	for(ri i=1;i<=n;++i){
		for(ri j=1;j<=k;++j){
			if(a[i]==j||a[i]==-1){
				f[i][j]=(ans[i-1]-g[j]+mod)%mod;
				++cnt[j];
				if(cnt[j]>=len-1)g[j]=(ans[i-len+1]-f[i-len+1][j]+mod)%mod;
			}
			else cnt[j]=g[j]=0;
			ans[i]=(ans[i]+f[i][j])%mod;
		}
	}
	cout<<ans[n];
	return 0;
}

G题

传送门 有点可惜

比赛的时候没时间做了233。

我们考虑如同scoi2018pipiscoi2018pipiscoi2018pipi酱的日常那种做法,把绝对值拆开。

即拆开曼哈顿距离乱搞。

相当于维护∑i=1k(+ai/−ai)\sum_{i=1}^k(+a_i/-a_i)∑i=1k​(+ai​/−ai​)的区间最大值。

什么意思呢?

对于一个点ppp,我们把它的各维度的不同组合方式用2k2^k2k个状态存起来。

准确地说,就是每个二进制位表示这个点在这个维度上是正的还是负的贡献(不妨设000为负111为正),记做statep,0...2k−1state_{p,0...2^k-1}statep,0...2k−1​。

对于两个点(a1,a2,...,ak),(b1,b2,...,bk)(a_1,a_2,...,a_k),(b_1,b_2,...,b_k)(a1​,a2​,...,ak​),(b1​,b2​,...,bk​),他们的距离是等于max{statea,i+stateb,2k−i−1}max\{state_{a,i}+state_{b,2^k-i-1}\}max{statea,i​+stateb,2k−i−1​}的。

于是维护区间的statestatestate变量的最大值然后加起来取maxmaxmax就可以了。

代码:

#include<bits/stdc++.h>
#define ri register int
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
using namespace std;
const int N=2e5+5;
inline int read(){
    int ans=0,w=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans*w;
}
int n,K,m,a[N][5],ans[32],up;
struct Node{int l,r,mx[32];}T[N<<2];
inline void pushup(int p){for(ri i=0;i<up;++i)T[p].mx[i]=max(T[lc].mx[i],T[rc].mx[i]);}
inline void build(int p,int l,int r){
	T[p].l=l,T[p].r=r;
	if(l==r){
		for(ri i=0;i<up;++i){
			int sum=0;
			for(ri j=0;j<K;++j){
				if((i>>j)&1)sum+=a[l][j];
				else sum-=a[l][j];
			}
			T[p].mx[i]=sum;
		}
		return;
	}
	build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline void update(int p,int k){
	if(T[p].l==T[p].r){
		for(ri i=0,sum=0;i<up;++i,sum=0){
			for(ri j=0;j<K;++j){
				if((i>>j)&1)sum+=a[k][j];
				else sum-=a[k][j];
			}
			T[p].mx[i]=sum;
		}
		return;
	}
	if(k<=mid)update(lc,k);
	else update(rc,k);
	pushup(p);
}
inline void query(int p,int ql,int qr){
	if(ql<=T[p].l&&T[p].r<=qr){
		for(ri i=0;i<up;++i)ans[i]=max(ans[i],T[p].mx[i]);
		return;
	}
	if(qr<=mid)query(lc,ql,qr);
	else if(ql>mid)query(rc,ql,qr);
	else query(lc,ql,mid),query(rc,mid+1,qr);
}
int main(){
	freopen("lx.in","r",stdin);
	n=read(),K=read(),up=1<<K;
	for(ri i=1;i<=n;++i)for(ri j=0;j<K;++j)a[i][j]=read();
	build(1,1,n);
	m=read();
	while(m--){
		int op=read();
		if(op==1){
			int x=read();
			for(ri i=0;i<K;++i)a[x][i]=read();
			update(1,x);
		}
		else{
			int l=read(),r=read();
			for(ri i=0;i<up;++i)ans[i]=-0x3f3f3f3f;
			query(1,l,r);
			int pri=0;
			for(ri i=0;i<up;++i)pri=max(pri,ans[i]+ans[up-i-1]);
			cout<<pri<<'\n';
		}
	}
	return 0;
}

Codeforces 1093 简要题解的更多相关文章

  1. Codeforces 863 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...

  2. Codeforces 381 简要题解

    做的太糟糕了...第一题看成两人都取最优策略,写了个n^2的dp,还好pre-test良心(感觉TC和CF的pretest还是很靠谱的),让我反复过不去,仔细看题原来是取两边最大的啊!!!前30分钟就 ...

  3. Codeforces 1120 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述:给你一个mmm个数的数列,现在规定把一个数列的1,2,...,k1,2,...,k1,2,...,k分成第一组,把k+1, ...

  4. Codeforces 1098 简要题解

    文章目录 前言 A题 B题 C题 D题 E题 传送门 前言 没错因为蒟蒻太菜了这场的最后一道题也咕掉了,只有AAA至EEE的题解233 A题 传送门 题意简述:给出一棵带点权的树,根节点深度为111, ...

  5. Codeforces 1110 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...

  6. Codeforces 380 简要题解

    ABC见上一篇. 感觉这场比赛很有数学气息. D: 显然必须要贴着之前的人坐下. 首先考虑没有限制的方案数.就是2n - 1(我们把1固定,其他的都只有两种方案,放完后长度为n) 我们发现对于一个限制 ...

  7. Codeforces 845 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意:2n2n2n个人下棋,分为两个阵营,每个阵营nnn个人,每个人有一个积分,积分高的能赢积分低的,问如果你可以随意选人,然 ...

  8. Codeforces 1065 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 GGG题略难,膜了一波zhouyuyang{\color{red} zhouyuyang}zhouyuyang巨佬的代码. 其余都挺清真的. ...

  9. Codeforces 888 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:给一个数列,问有多少个峰值点(同时比两边都大/小的点) 思路:按照题意模拟. 代码: #include<bit ...

随机推荐

  1. Android 各个版本新特性

    一.Android 4.x 新锁屏界面: Android4.0重新设计了锁屏幕UI,下方的解锁虚拟按键向周围发射出微光,轻轻拖动就可以解锁,比原来在UI上确实有很大的进步. 全新Widget排列: 主 ...

  2. e-olymp Problem9 N-digit numbers(打表)

    传送门:点我 N-digit numbers Find the quantity of N-digit numbers, which the sum is equal to their product ...

  3. 137. Single Number II (Bit)

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  4. Java_9 面向对象

    1.面向对象思想 面向过程的思想:自己做什么 面向对象的思想:自己找谁做,即不断地创造对象.使用对象.指挥对象做事情.万物皆对象. 面对对象的特征:封装.继承.多态. 2.java中基本单元类 成员变 ...

  5. 快速将磁盘的MBR分区方式改成GPT分区方式

    1.按Shift + F10打开命令提示符. 2.diskpart 3.list disk(列出所有磁盘) 4.select disk 0(选择磁盘) 5.clean(格式化所选的磁盘) 7.conv ...

  6. java传统web项目添加maven管理jar包,log4j无法正常输出日志

    本文适合1年以上编程基础的开发人员阅读,非技术创新,可作为故障排除实录参考/收藏. 背景 笔者最近在给公司一个老的web项目改造升级,项目使用springmvc+mybatis,由于项目比较久远,没有 ...

  7. Spring Boot 2.0(三):使用 Docker 部署 Spring Boot

    Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...

  8. Spring Boot 2.0(二):Spring Boot 开源软件都有哪些?(转)

    2016年 Spring Boot 还没有被广泛使用,在网上查找相关开源软件的时候没有发现几个,到了现在经过2年的发展,很多互联网公司已经将 Spring Boot 搬上了生产,而使用 Spring ...

  9. hdu 2119(简单二分图) Matrix

    http://acm.hdu.edu.cn/showproblem.php?pid=2119 一个由0和1构成的矩阵,每次选取一行或者一列将其中的1变成0,求最小删除次数 简单的二分图应用,矩阵的横坐 ...

  10. 添加exe为windows service服务

    [方法一] 一.介绍 srvany.exe是Microsoft Windows Resource Kits工具集的一个实用小工具,用于将EXE程序作为Windows服务运行.srvany是其注册程序的 ...