首页 > 其他分享 >9.26-CSP-S模拟12

9.26-CSP-S模拟12

时间:2022-09-26 18:55:06浏览次数:56  
标签:typedef 12 9.26 int Rep long maxn CSP define

T1 开挂

比较水的贪心题,可以证明一定只包含不相交,拿个栈就很好做了。

点击查看代码
#include <bits/stdc++.h>
typedef long long ll;typedef unsigned long long ull; typedef double db;typedef long double ldb;
#define fre(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define Rep(i,a,b) for(int i=a;i<=b;++i) 
#define Dwn(i,a,b) for(int i=a;i>=b;--i)
#define pii pair<int,int>
#define mair make_pair
#define fir first
#define sec second
using namespace std;

const int maxn=1e6+10;

int n,a[maxn],b[maxn];
vector<int>ned,spt;

void solve(){
	cin>>n;Rep(i,1,n)cin>>a[i];Rep(i,1,n)cin>>b[i];
	sort(a+1,a+n+1);
	Rep(i,2,n){
		if(a[i]==a[i-1]){
			ned.push_back(a[i]);
		}else {
			for(int j=a[i-1]+1;j<a[i] && (!ned.empty());++j){
				spt.push_back(j-ned.back());ned.pop_back();
			}
		}
	}
	int now=a[n]+1;
	while(!ned.empty()){ spt.push_back(now-ned.back());ned.pop_back();++now; }
	sort(b+1,b+n+1);
	ull ans=0;
	if(!spt.empty()){
		sort(spt.begin(),spt.end());
		int it=1;
		Dwn(i,spt.size()-1,0){
			ans+=1LL*b[it]*spt[i];
			++it;
		}
	}
	cout<<ans<<"\n";
}

int main (){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);return solve(),0; }


T2 叁仟柒佰万

比较水的dp题,可以处理出最后一个段以i结尾时,前i个数分为若干段的方案数,显然是求出一个最大的左端点使得区间mex恰好达到要求,左端点之前的所有位置都可以转移过来,维护前缀和就行。

点击查看代码
#include <bits/stdc++.h>
typedef long long ll;typedef unsigned long long ull; typedef double db;typedef long double ldb;
#define fre(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define Rep(i,a,b) for(int i=a;i<=b;++i) 
#define Dwn(i,a,b) for(int i=a;i>=b;--i)
#define pii pair<int,int>
#define mair make_pair
#define fir first
#define sec second
using namespace std;

const int maxn=3.7e7+10,Mod=1e9+7;
const ll B=262143;

#define gc if(++ip==ie)fread(ip=buf,1,SZ,stdin)
const int SZ=1<<21;char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int read(){ gc;while(*ip<'-')gc; bool f=*ip=='-';if(f)gc; int x=*ip&15;gc; while(*ip>'-'){x*=10;x+=*ip&15;gc;} return f ? -x : x; }

int tex,n;
int a[maxn];
int Mex,vis[300000],AMex;
int	f[maxn],L[maxn];

void solve(){
	n=read();
	Mex=AMex=0;
	if(n==37000000){
		int x,y;x=read(),y=read();
		a[1]=0;Rep(i,2,n)a[i]=(1LL*a[i-1]*x+y+i)&B;
	}else Rep(i,1,n)a[i]=read();
	Rep(i,1,n){ ++vis[a[i]]; while(vis[Mex])++Mex; }
	Rep(i,1,n)vis[a[i]]=f[i]=0;
	AMex=Mex,Mex=0;
	int ED=0;
	Dwn(i,n,1){
		++vis[a[i]];
		while(vis[Mex])++Mex;
		if(Mex==AMex){ ED=i;break; }
	}
	Rep(i,ED,n)vis[a[i]]=0;Mex=0;
	int l=1,ans=0;
	f[0]=1;
	for(int i=1;i<ED;++i){
		++vis[a[i]];
		while(vis[Mex])++Mex;
		if(Mex==AMex){
			while(l<i && (a[l]>Mex || (vis[a[l]]>1))){--vis[a[l]];++l;}
			L[i]=l;
		}else L[i]=-1;
		if(L[i]!=-1){ f[i]=f[L[i]-1];ans=(ans+f[i])%Mod; }
		f[i]=(f[i]+f[i-1])%Mod;
	}
	Rep(i,1,n)vis[a[i]]=0;
	cout<<(ans+1)%Mod<<"\n";

}

int main (){ tex=read();while(tex--)solve();return 0; }

T3 超级加倍

用了笛卡尔树,建出笛卡尔树使得两点树上路径的最大/小值为笛卡尔树上两点的lca,于是在大根/小根笛卡尔树上同时互为祖先关系的点对就是要求的路径数量,求这样的点对就是将一棵树转为dfs序,然后搜另一棵树,用BIT维护当前点到根的路径上出现了哪些dfs序,然后在BIT上查原来有几个点在它子树内就行。

点击查看代码
#include <bits/stdc++.h>
typedef long long ll;typedef unsigned long long ull; typedef double db;typedef long double ldb;
#define fre(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define Rep(i,a,b) for(int i=a;i<=b;++i) 
#define Dwn(i,a,b) for(int i=a;i>=b;--i)
#define pii pair<int,int>
#define mair make_pair
#define fir first
#define sec second
using namespace std;

const int maxn=2e6+10;

int n;
ll ans;
int a[maxn];

struct BIT{
	int c[maxn];
	#define lowbit(x) (x&-x)
	void Add(int x,int d){ for(;x<=n;x+=lowbit(x))c[x]+=d; }
	int Query(int x){ 
		int res=0;for(;x;x-=lowbit(x))res+=c[x];return res; 
	}
	int Range(int x,int y){ return Query(y)-Query(x-1); }
}B;

struct Graph{
	struct eg{int from,to,next;}e[maxn*2];
	int len,head[maxn];int f[maxn];int fa[maxn];bool vis[maxn];
	void lqx(int from,int to)
	{ e[++len].from=from,e[len].to=to,e[len].next=head[from],head[from]=len; }
}G;
struct CTT{
	struct eg{int from,to,next;}e[maxn*2];
	int f[maxn];
	int Find(int x){return f[x]==x ? x : f[x]=Find(f[x]);}
	void Init(){ Rep(i,1,n)f[i]=i; }
	int len,head[maxn];
	void lqx(int from,int to)
	{ e[++len].from=from,e[len].to=to,e[len].next=head[from],head[from]=len; }
	void Build1(){
		Init();
		Rep(u,1,n){
			for(int i=G.head[u];i;i=G.e[i].next){
				int v=G.e[i].to;
				if(v<u){
					if(Find(u)==Find(v))continue;
					lqx(Find(u),Find(v));
					f[Find(v)]=Find(u);
				}
			}
		}
	}
	void Build2(){
		Init();
		Dwn(u,n,1){
			for(int i=G.head[u];i;i=G.e[i].next){
				int v=G.e[i].to;
				if(v>u){
					if(Find(u)==Find(v))continue;
					lqx(Find(u),Find(v));
					f[Find(v)]=Find(u);
				}
			}
		}
	}
}T,E;

int st[maxn],ed[maxn],Te;

void Dfs1(int u){ 
	st[u]=++Te;
	for(int i=T.head[u];i;i=T.e[i].next){ int v=T.e[i].to; Dfs1(v); } ed[u]=Te; 
}
void Dfs2(int u){
	ans+=B.Range(st[u],ed[u]);
	B.Add(st[u],1);
	for(int i=E.head[u];i;i=E.e[i].next){ int v=E.e[i].to; Dfs2(v); }
	B.Add(st[u],-1);
}

void solve(){
	cin>>n;int x;
	Rep(i,1,n){ cin>>x;if(x)G.lqx(i,x),G.lqx(x,i); }
	T.Build1(),E.Build2();
	Dfs1(n),Dfs2(1);
	cout<<ans<<"\n";
}

int main (){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);return solve(),0; }


T4 欢乐豆

提取子图最短路。

如果没有特殊边,那么显然每个源到的所有点最短路都是源的点权。所以当一个点没有被特殊边涉及时,直接如此求即可。对于被特殊边涉及的点,点数规模较小,他们通过特殊边相连构成若干联通块,对于每个块可以求出块内全源最短路,然后算总和。
路径类型分为

  • 块内 \(\rightarrow\) 块内
  • 块内 \(\rightarrow\) 块外
  • 块内 \(\rightarrow\) 块外 \(\rightarrow\) 块内

前两种就普通dij,用线段树模拟,第三种显然只能是在块内走一段,然后走到点权最小的一个块外点再走回来,算答案的时候特殊考虑一下就行

点击查看代码
#include <bits/stdc++.h>
typedef long long ll;typedef unsigned long long ull; typedef double db;typedef long double ldb;
#define fre(x) freopen(#x ".in","r",stdin),freopen(#x ".out","w",stdout)
#define Rep(i,a,b) for(int i=a;i<=(int)b;++i) 
#define Dwn(i,a,b) for(int i=a;i>=(int)b;--i)
#define pii pair<int,int>
#define mair make_pair
#define fir first
#define sec second
#define int ll
using namespace std;

const int maxn=1e5+10,INF=1e17+20051107;

int n,m;
ll ans;
int a[maxn],id[maxn],ind;
multiset<int>MS;
vector<int>pts[maxn];
vector<pii>vec[maxn];
int ud[maxn],dis[maxn];

struct UN{
	int f[maxn],siz[maxn];
	void Init(int n){ Rep(i,1,n)f[i]=i,siz[i]=1; }
	int Find(int x){ return f[x]==x ? x : f[x]=Find(f[x]); }
	void Merge(int x,int y){ x=Find(x),y=Find(y); if(x==y)return; f[y]=x,siz[x]+=siz[y]; }
}S;

struct Seg{
	struct Tree{ int mini,pos,lazy,tag; }tr[maxn<<2];
	void Pushup(int rt){
		tr[rt].mini=min(tr[rt<<1].mini,tr[rt<<1|1].mini);
		if(tr[rt].mini==tr[rt<<1].mini &&(!tr[rt<<1].tag))tr[rt].pos=tr[rt<<1].pos;
		else tr[rt].pos=tr[rt<<1|1].pos;
		tr[rt].tag=tr[rt<<1].tag&tr[rt<<1|1].tag;
	}
	void Build(int rt,int l,int r){
		tr[rt].mini=tr[rt].lazy=INF;tr[rt].tag=0,tr[rt].pos=l;
		if(l==r)return;
		int mid=(l+r)>>1;
		Build(rt<<1,l,mid),Build(rt<<1|1,mid+1,r);
	}
	void Update(int rt,int w){tr[rt].mini=min(tr[rt].mini,w),tr[rt].lazy=min(tr[rt].lazy,w);}
	void Pushdown(int rt){
		if(tr[rt].lazy==INF)return;
		if(!tr[rt<<1].tag)Update(rt<<1,tr[rt].lazy);
		if(!tr[rt<<1|1].tag)Update(rt<<1|1,tr[rt].lazy);
		tr[rt].lazy=INF;
	}
	void Delete(int rt,int l,int r,int x){
		if(l==r)return tr[rt].mini=INF,tr[rt].tag=1,void();
		int mid=(l+r)>>1;Pushdown(rt);
		if(x<=mid)Delete(rt<<1,l,mid,x);
		else Delete(rt<<1|1,mid+1,r,x);
		Pushup(rt);
	}
	void Modify(int rt,int l,int r,int s,int t,int w){
		if(tr[rt].tag || t<s)return;
		if(s<=l && t>=r)return Update(rt,w);
		int mid=(l+r)>>1;Pushdown(rt);
		if(s<=mid)Modify(rt<<1,l,mid,s,t,w);
		if(t>mid)Modify(rt<<1|1,mid+1,r,s,t,w);
		Pushup(rt);
	}
}T;

void Dij(int i,int u){
	T.Build(1,1,pts[i].size());
	T.Modify(1,1,pts[i].size(),ud[u],ud[u],0);
	dis[ud[u]]=0;
	while(T.tr[1].mini!=INF){
		int x=T.tr[1].pos,dd=T.tr[1].mini,last=1;
		dis[x]=dd;T.Delete(1,1,pts[i].size(),x);
		x=pts[i][x-1];
		for(auto it : vec[x]){
			T.Modify(1,1,pts[i].size(),last,ud[it.fir]-1,a[x]+dd);
			T.Modify(1,1,pts[i].size(),ud[it.fir],ud[it.fir],dd+it.sec);
			last=ud[it.fir]+1;
		}
		T.Modify(1,1,pts[i].size(),last,pts[i].size(),dd+a[x]);
	}
}

void solve(){
	cin>>n>>m;Rep(i,1,n)cin>>a[i],MS.insert(a[i]);
	int x,y,w;S.Init(n);
	Rep(i,1,m){ cin>>x>>y>>w;vec[x].emplace_back(y,w);S.Merge(x,y); }
	Rep(i,1,n){
		sort(vec[i].begin(),vec[i].end());
		if(S.Find(i)==i && S.siz[i]>1)id[i]=++ind;
	}
	Rep(i,1,n){
		if(S.siz[S.Find(i)]>1)pts[id[S.Find(i)]].push_back(i);
		else ans+=(n-1)*a[i];
	}
	Rep(i,1,ind){
		for(int j=0;j<(int)pts[i].size();++j){ ud[pts[i][j]]=j+1;MS.erase(MS.find(a[pts[i][j]])); }
		int tmp= MS.empty() ? INF : (*MS.begin());
		for(auto u : pts[i]){
			Dij(i,u);
			int mini=INF;
			Rep(j,1,pts[i].size())mini=min(mini,dis[j]+a[pts[i][j-1]]);
			Rep(j,1,pts[i].size())ans+=min(dis[j],mini+tmp);
			ans+=mini*(n-pts[i].size());
		}
		for(auto u : pts[i])MS.insert(a[u]);
	}
	cout<<ans<<"\n";
}

#undef int
int main (){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);return solve(),0; }

标签:typedef,12,9.26,int,Rep,long,maxn,CSP,define
From: https://www.cnblogs.com/Delov/p/16731982.html

相关文章

  • 2022.9.26比赛记录
    T1题意给定两个长度为\(n\)的序列\(a,b\),选择一个最长的区间\([l,r]\)使得\(\sum\limits_{i=l}^ra_i\ge0\)并且\(\sum\limits_{i=l}^rb_i\ge0\)。输出这个......
  • 9.26
    今日内容1.基本数据类型2.与用户交互3.格式化输出4.基本运算符5.常用赋值符6.逻辑运算符7.成员运算符8.身份运算符基本数据类型整型就是整数int代码实现:age......
  • javascript: 自定义鼠标拖动的滑块slider(chrome 105.0.5195.125)
    一,js代码<html><head><metacharset="utf-8"/><title>测试</title></head><bodyonmousemove="divmousemoving()"onMouseUp="divmouseup()"><divstyle=......
  • CSP2022 S2 练习二 题解
    ArbitrageA货币可以以\(x\)的汇率兑换B货币,就从A向B连一条权值为\(x\)的边,改一下\(Floyd\)即可。点击查看代码#include<iostream>#include<string>#i......
  • 12. NumPy相关数组操作
    1.前言NumPy中包含了一些处理数组的常用方法,大致可分为以下几类:数组变维操作数组转置操作修改数组维度操作连接与分割数组操作下面分别对它们进行介绍。2.数组......
  • 闲话 22.9.26
    闲话调全体T4六点改出来了,但大样例不认为我改出来了于是又花了两个小时修改不存在的错误最近在做这题[JRKSJR4]risrqnis想做主要是因为上琴糖但是做着做着发现很......
  • 4.门面Slf4j+slf4j-log4j12+log4j
    1.导入pom依赖<!--slf4jcore使用slf4j必須添加--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.27</ver......
  • 2022-2023-1 20221312 《计算机基础与程序设计》第四周学习总结
    作业信息班级链接:首页-2022-2023-1-计算机基础与程序设计-北京电子科技学院-班级博客-博客园(cnblogs.com)作业要求:2022-2023-1《计算机基础与程序设计》教学......
  • 重复暴FRB 20201124A的观测和模型
    重复暴FRB20201124A的观测和模型ArticlePublished:21September2022AfastradioburstsourceatacomplexmagnetizedsiteinabarredgalaxyH.Xu,J.R.Ni......
  • CSP202206_4
    CSP202206_4目录CSP202206_4题目思路Code题目光线追踪思路最初对整体分析了一下,因为反射点都是整数,而反射的性质典型而有限,一开始莫名想着是不是可以推规律,结果白白浪......