首页 > 其他分享 >NOIP 模拟 18

NOIP 模拟 18

时间:2024-11-21 19:18:40浏览次数:1  
标签:res NOIP mathit int 18 MAXN ans 操作 模拟

NOIP 模拟 18

最近老是犯唐,这次也是。

T1

容易得到暴力代码:

namespace s1{
	bool sta[MAXN*MAXN];
	bool S[MAXN],T[MAXN];
	string s;
	int ans;
	int main(){
        cin>>n>>m;
		for(int i=1;i<=m;++i){
			cin>>s;
			memset(S,0,sizeof(bool)*(n+5));
			memset(T,0,sizeof(bool)*(n+5));
			for(int j=0;j<n;++j)
				switch(s[j]){
					case '0': break;
					case '1': T[j+1]=1;break;
					case '2': S[j+1]=1;break;
					default:  S[j+1]=T[j+1]=1;break;
				}
			for(int i=1;i<=n;++i)
				for(int j=i+1;j<=n;++j)	
					if((S[i]&&T[j])||(S[j]&&T[i]))
						sta[i*(n-1)+j]^=1;
		}
		for(int i=1;i<=n;++i)
			for(int j=i+1;j<=n;++j)
				if(sta[i*(n-1)+j])
					++ans;
		cout<<ans<<'\n';
		return 0;
	}
}

其实就是模拟题面的过程。我们发现 \(n\le10^4\),是可以通过 \(O(n^2)\) 的算法的。暴力程序真正的瓶颈在于每次都 \(n^2\) 枚举而外面又套了一个 \(m\),复杂度变成 \(O(mn^2)\),无法通过。

发现每次的 \(n^2\) 枚举的内部都只是简单的位运算 + 异或。不难想到 \(\textbf{bitset}\) 处理。具体地,将所有的 bool 全换成 bitset,然后:

  • 若 \(S_i=1\),则 \(\mathit{ans}_i\gets\mathit{ans}_i\oplus T_i\);
  • 若 \(T_i=1\),则 \(\mathit{ans}_i\gets\mathit{ans}_i\oplus S_i\);
  • 若 \(S_i=1\land T_i=1\),这时候会算重一次,只需 \(\mathit{ans}_i\gets\mathit{ans_i}\oplus(S_i\;\&\;T_i)\)。

然后就没了。本质上就是把 \(n^2\) 的枚举用 bitset 一步到位了。

for(int i=1,s,t;i<=n;++i){
    s=S[i],t=T[i];
    S[i]=T[i]=0;
    if(s) mp[i]^=T;
    if(t) mp[i]^=S;
    if(s&&t) mp[i]^=S&T;
}
for(int i=1;i<=n;++i)
    for(int j=i+1;j<=n;++j)
        if(mp[i][j])
            ++ans;
cout<<ans<<'\n';
return 0;

评价:bitset 使用不够熟练。考场上以为是什么神仙性质题,关键是还真推出来了只有 \(1\) 和 \(2\) 时的性质,于是就一直在错误的方向上摸索。

T2 序列

首先必须想到的一步转化:将所有操作转化为将总答案乘上一个数

那么对于操作一,转化为贡献 \(\dfrac y{a_x}\);对于操作二,转化为贡献 \(\dfrac{a_x+y}{a_x}\);对于操作三,直接就是贡献 \(y\)。

然而这样做会有一个问题,比如操作一,一旦之前有对 \(a_x\) 操作,那么 \(a_x\) 的值就会改变。也就是说,我们对一次操作的贡献无法静态算出。操作二也同理。

其实操作一导致的问题是好解决的,只需要取对 \(\forall a_x\) 的所有操作一中 \(y\) 的最大值,然后操作一就可以转化为操作二:把 \(a_x\) 修改为 \(y\) 相当于加上 \(y-a_x\)。但是,操作二造成的影响我们似乎真的不好处理。

考场上想到这就止步了。

但实际上,有一个显然的性质:对 \(\forall a_x\) 的加法操作中,我们肯定先操作 \(y\) 大的,然后再操作 \(y\) 小的。于是,当我们对 \(y_i\) 计算贡献时,此时的 \(a_x\) 实际上已经变为 \(a_x+\sum_{y_j>y_i}y_j\)。这只需要我们对于任意点的操作二进行从大到小排序,然后操作二的贡献我们就可以计算了。

于是我们将所有的操作都转化为了对总答案乘上一个数。从大到小排序,然后挨个计算并输出即可。

#include<bits/stdc++.h>
#define fw fwrite(obuf,p3-obuf,1,stdout)
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#define putchar(x) (p3-obuf<1<<20?(*p3++=(x)):(fw,p3=obuf,*p3++=(x)))
#define int long long
using namespace std;

char buf[1<<20],obuf[1<<20],*p1=buf,*p2=buf,*p3=obuf,str[20<<2];
int read(){
	int x=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x;
}
template<typename T>
void write(T x,char sf='\n'){
	if(x<0)putchar('-'),x=~x+1;
	int top=0;
	do str[top++]=x%10,x/=10;while(x);
	while(top)putchar(str[--top]+48);
	if(sf^'#')putchar(sf);
}
constexpr int MAXN=1e5+5,MOD=1e9+7;
int n,m,a[MAXN],ans=1;
vector<int>pls[MAXN];
int chg[MAXN];
vector<pair<double,int>>f;
int max(int a,int b){
	return a>b?a:b;
}
int power(int a,int b){
	int res=1;
	for(;b;a=a*a%MOD,b>>=1)if(b&1)res=res*a%MOD;
	return res; 
}

signed main(){
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n;++i) a[i]=read();
	for(int i=1,t,x,y;i<=m;++i){
		t=read(),x=read(),y=read();
		switch(t){
			case 1: chg[x]=max(chg[x],y);break;
			case 2: pls[x].emplace_back(y);break;
			default:f.emplace_back(y,y);
		}
	}
	for(int i=1,t;i<=n;++i){
		if(a[i]<chg[i]) pls[i].emplace_back(chg[i]-a[i]);
		sort(pls[i].begin(),pls[i].end(),greater<>());
		t=a[i];
		for(auto x:pls[i]){
			f.emplace_back(1.0*(t+x)/t,(t+x)*power(t,MOD-2)%MOD);
			t+=x;
		}
	}
	sort(f.begin(),f.end(),greater<>());
	for(int i=1;i<=n;++i) ans=ans*a[i]%MOD;
	for(auto x:f){
		write(ans,' ');
		ans=ans*x.second%MOD;
	}
	for(int i=f.size();i<=m;++i) write(ans,' ');
	return fw,0;
}

T3

什么神仙题。

T4 字符串

有一道基本相同的题目:CF610E

题目中 “插入字符” 操作不好维护,观察到 \(t\) 是一个排列,所以每个字母在 \(t\) 中仅会出现一次。故有引理:

任意字符 \(s_i\) 和 \(s_{i+1}\) 在一个循环节中,当且仅当 \(s_i\) 和 \(s_{i+1}\) 在 \(t\) 中相邻。

所以将每个字符按照在 \(t\) 中的位置编号,则原串转化为一个数字串,我们要求的就是数字串的逆序对数。区间修改显然线段树维护,在每个线段树节点上设 \(\mathit{sm}_{i,j}\) 为 \([l,r]\) 中每一对相邻的字符中 \((\forall k)~s_k=i\land s_{k+1}=j\) 的数有多少个。复杂度 \(O(mk^2\log n)\)。

#include<bits/stdc++.h>
#define lp p<<1
#define rp p<<1|1
#define mid ((s+t)>>1)
using namespace std;

constexpr int MAXN=2e5+5;
int n,m,k,tmp[10][10];
string S;
struct SegTree{
	int lc,rc,sm[10][10],lazy;
	SegTree(){
		lc=rc=lazy=0;
		memset(sm,0,sizeof(sm));
	}
	int*operator[](const int&x){
		return sm[x];
	}
}st[MAXN<<2];
void pushup(int p){
	for(int i=0;i<k;++i)
		for(int j=0;j<k;++j)	
			st[p][i][j]=st[lp][i][j]+st[rp][i][j];
	st[p].lc=st[lp].lc,st[p].rc=st[rp].rc;
	++st[p][st[lp].rc][st[rp].lc];
}
void build(int s,int t,int p){
	if(s==t){
		st[p].lc=st[p].rc=S[s]-'a';
		return;
	}
	build(s,mid,lp),build(mid+1,t,rp);
	pushup(p);
}
void pushlazy(int p,int c){
	for(int i=0;i<k;++i)
		for(int j=0;j<k;++j)
			tmp[i][j]=st[p][i][j];
	for(int i=0;i<k;++i)
		for(int j=0;j<k;++j)
			st[p][(i+c)%k][(j+c)%k]=tmp[i][j],tmp[i][j]=0;
	st[p].lc=(st[p].lc+c)%k;
	st[p].rc=(st[p].rc+c)%k;
	st[p].lazy=(st[p].lazy+c)%k;
}
void pushdown(int p){
	if(!st[p].lazy) return;
	pushlazy(lp,st[p].lazy);
	pushlazy(rp,st[p].lazy);
	st[p].lazy=0;
}
void mdf(int l,int r,int c,int s=1,int t=n,int p=1){
	if(l<=s&&t<=r) return pushlazy(p,c),void();
	pushdown(p);
	if(l<=mid) mdf(l,r,c,s,mid,lp);
	if(mid<r) mdf(l,r,c,mid+1,t,rp);
	pushup(p);
}
SegTree ask(int l,int r,int s=1,int t=n,int p=1){
	if(l<=s&&t<=r) return st[p];
	pushdown(p);
	if(l>mid) return ask(l,r,mid+1,t,rp);
	if(mid>=r) return ask(l,r,s,mid,lp);
	SegTree res1=ask(l,r,s,mid,lp),res2=ask(l,r,mid+1,t,rp),res;
	for(int i=0;i<k;++i)
		for(int j=0;j<k;++j)
			res[i][j]=res1[i][j]+res2[i][j];
	res.lc=res1.lc,res.rc=res2.rc;
	++res[res1.rc][res2.lc];
	return res;
}

int main(){
	freopen("d.in","r",stdin);
	freopen("d.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>n>>m>>k>>S;
	S=' '+S;
	build(1,n,1);
	while(m--){
		int op,l,r;
		cin>>op>>l>>r;
		switch(op){
			case 1:{
				int c;
				cin>>c;
				mdf(l,r,c);
				break;
			}default:{
				string s;
				cin>>s;
				int ans=0;
				SegTree res=ask(l,r);
				for(int i=0;i<k;++i)
					for(int j=0;j<=i;++j)
						ans+=res[s[i]-'a'][s[j]-'a'];
				cout<<ans+1<<'\n';
				break;
			}
		} 
	}
	return 0;
}

标签:res,NOIP,mathit,int,18,MAXN,ans,操作,模拟
From: https://www.cnblogs.com/laoshan-plus/p/18561369

相关文章

  • [NOIP2016 提高组] 蚯蚓 题解
    考场思路考虑要动态维护最大值,可以直接使用优先队列进行维护,但是,考虑到我们并不好直接修改优先队列中的每一个元素,所以决定使用vector先排一遍序,再使用冒泡排序进行动态维护,时间复杂度\(O(mn)\),可以拿35pts。代码#include<iostream>#include<vector>#include<algorithm>......
  • 【Flinkcdc问题解决】java.lang.NoClassDefFoundError: org/apache/flink/shaded/guav
    1.环境介绍Flink1.17+Flinkcdc2.2.12.问题描述使用Flink1.17和Flinkcdc2.2.1环境进行数据加工,但是报以上错误,原因是版本不匹配,flinkcdc2.2.1用的是guava18,但是flink1.17用的是guava30,导致冲突。3.问题解决添加flink-sql-connector-mysql-cdc依赖<dependen......
  • [题解](更新中)2024/11/21 模拟赛 / 2023牛客OI赛前集训营-提高组(第二场) A~B
    整套都是原题所以就不设密码了(原题页面:https://ac.nowcoder.com/acm/contest/65193题解:https://www.nowcoder.com/discuss/540225827162583040\(60+30+20+20=130\)。每日挂分之T2线段树不开\(4\)倍+\(10^6\)数量级输入不关同步流,\(\bf\colorbox{MidnightBlue}{\texttt{\color{......
  • [NOIP2022] 建造军营
    前言米奇妙妙\(\rm{dp}\),也是高端计数这种题看得懂想不出,还是非常难蚌能不能多想想再去看\(\rm{TJ}\)啊算法注意到除了割边,其他的边都没有影响,显然可以缩\(\rm{e}\)-\(\rm{DCC}\)再进行处理这里发现缩完之后形成一棵树,考虑树形\(\rm{dp}\)这里我有一个误......
  • 国标GB28181-2016平台LiteGBS国标GB28181公网直播接入设备端怎么配置GB28181参数
    LiteGBS国标GB28181公网直播是一款强大的基于国标GB28181协议的视频云服务平台,它支持多路设备同时接入,在安防领域发挥着重要作用。LiteGBS国标GB28181-2016平台可进行解码、处理、分发等服务,能将接入的视频流转换为多种格式,如RTSP、RTMP、FLV、HLS、WebRTC等,兼容全平台、全终端,满......
  • 国标GB28181软件LiteGBS国标GB28181公网平台在Android端实现设备接入的语音对讲
    在智能安防领域,GB28181协议已经成为一种广泛应用的通信标准。通过该协议,可以实现不同品牌和型号的安防设备之间的互联互通。而在Android平台上实现GB28181设备接入端的语音广播和语音对讲功能,对于提升安防监控系统的实时性和交互性具有重要意义。而在功能方面,LiteGBS国标GB28181......
  • 18、解析1_2(硬解析、共享sql、统计信息影响)
    硬解析清空sharedpool:SQL>altersystemflushshared_pool;Systemaltered.感知硬解析的存在模拟一个硬解析,trace文件具体看递归SQL,以及需要访问的一些字典表查询会话sid、serial#:SQL>selectsidfromv$mystatwhererownum=1;SID----------926......
  • NOIP 前随机选做
    CSP奋战两小时arena死活调不出,奇耻大辱哦。不如加练。20241028CSP-S2024T4很需要大脑清醒的一道题。自底往上对于每个询问\(\mathcalO(\logn)\)做是没有救的,大概就是从\(u\)开始往上跳,维护可以赢的确定的单点以及不会被已有点击败的未确定点的后缀。显然是要拆贡......
  • [网鼎杯 2018]Fakebook
    访问网站的robots.txt,看看有没有线索找到了user.php的源码,直接访问这个备份文件。下载完成直接打开用就好,记事本就可以打开.bak文件<?phpclassUserInfo{public$name="";public$age=0;public$blog="";publicfunction_......
  • 基于圆柱体镜子和光线跟踪实现镜反射观测全景观图的matlab模拟仿真
    1.程序功能描述基于圆柱体镜子和光线跟踪实现镜反射观测全景观图.模拟的场景如下所示: 2.测试软件版本以及运行结果展示MATLAB2022a版本运行 3.核心程序%%step1fori=1:mmx_new(i)=i-round(mm/2);endfori=1:nny_new(i)=i-round(nn/2);......